inch 0.1.3 → 0.1.4

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +5 -6
  3. data/TODOS.md +7 -0
  4. data/lib/inch/cli/arguments.rb +36 -2
  5. data/lib/inch/cli/command/base.rb +56 -8
  6. data/lib/inch/cli/command/base_list.rb +17 -3
  7. data/lib/inch/cli/command/base_object.rb +17 -4
  8. data/lib/inch/cli/command/options/base.rb +55 -10
  9. data/lib/inch/cli/command/options/base_list.rb +25 -5
  10. data/lib/inch/cli/command/options/base_object.rb +0 -2
  11. data/lib/inch/cli/command/options/list.rb +2 -2
  12. data/lib/inch/cli/command/options/show.rb +2 -2
  13. data/lib/inch/cli/command/options/suggest.rb +2 -2
  14. data/lib/inch/cli/command/output/base.rb +9 -0
  15. data/lib/inch/cli/command/output/console.rb +4 -0
  16. data/lib/inch/cli/command/output/inspect.rb +2 -2
  17. data/lib/inch/cli/command/output/list.rb +1 -1
  18. data/lib/inch/cli/command_parser.rb +30 -9
  19. data/lib/inch/code_object/nodoc_helper.rb +23 -2
  20. data/lib/inch/code_object/proxy.rb +16 -2
  21. data/lib/inch/code_object/proxy/base.rb +2 -23
  22. data/lib/inch/code_object/proxy/method_object.rb +1 -0
  23. data/lib/inch/code_object/proxy/method_parameter_object.rb +4 -1
  24. data/lib/inch/evaluation.rb +0 -2
  25. data/lib/inch/evaluation/base.rb +1 -0
  26. data/lib/inch/evaluation/constant_object.rb +0 -3
  27. data/lib/inch/evaluation/file.rb +0 -4
  28. data/lib/inch/evaluation/namespace_object.rb +1 -7
  29. data/lib/inch/evaluation/role/base.rb +29 -5
  30. data/lib/inch/evaluation/role/constant.rb +0 -5
  31. data/lib/inch/evaluation/role/object.rb +1 -5
  32. data/lib/inch/evaluation/score_range.rb +12 -0
  33. data/lib/inch/rake/suggest.rb +3 -0
  34. data/lib/inch/source_parser.rb +27 -1
  35. data/lib/inch/version.rb +1 -1
  36. data/test/fixtures/simple/lib/foo.rb +6 -0
  37. data/test/fixtures/simple/lib/role_namespaces.rb +15 -3
  38. data/test/inch/cli/command/base_test.rb +15 -0
  39. data/test/inch/cli/command/inspect_test.rb +9 -0
  40. data/test/inch/cli/command/list_test.rb +3 -0
  41. data/test/inch/cli/command/options/base_list_test.rb +50 -0
  42. data/test/inch/cli/command/options/base_object_test.rb +14 -0
  43. data/test/inch/cli/command/options/base_test.rb +8 -0
  44. data/test/inch/cli/command/suggest_test.rb +11 -0
  45. data/test/inch/cli/trace_helper_test.rb +47 -0
  46. data/test/inch/code_object/proxy_test.rb +10 -0
  47. data/test/integration/visibility_options_test.rb +24 -17
  48. data/test/test_helper.rb +80 -0
  49. metadata +13 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba6f65c0ae25dc579fbdef3eebccf8ada06f3d68
4
- data.tar.gz: 8485e6393a208e59aa9d961ec67117bd657b6ba8
3
+ metadata.gz: 94f45218f025da4fe625a569967db6d85e9231a0
4
+ data.tar.gz: 481b2138c2c48c35e1ca884e078d8265e578e39b
5
5
  SHA512:
6
- metadata.gz: 0f4ceeb144048f28a6ed9ca7f889be809a16a49c64e2ab7d572ecd59dee5b0442294c842d6da17adcd2ffe57c24f45ba4dbd3122fc65f53c3784d21a8c070899
7
- data.tar.gz: 7ed146606d3c0604cd0c574d8120d960c1ed1982039e97b51e423192341d5f5ff8a60d261375ceb1576ae272f9ce0d754ea15de3af8c5510b8660c68e6a6b1d9
6
+ metadata.gz: 9d91370b78a36eb2a5fbd9541109a2b4bc5f97d6b67e3ce0de0cf9d8f22617821a9cd359dae170de49a6a80dde0e79e8437556e2a800c331d0bd0c45b96ab429
7
+ data.tar.gz: c47ca4717186e9ed78161c3db7baa2742c1aac96a8208f0cae4e08c2b81a75bafe42fd23f356680180165b2dbe94cf69855c59a1fdfa0d3683ec2d79bac37e2b
data/README.md CHANGED
@@ -1,12 +1,10 @@
1
- # Inch
1
+ # Inch [![Build Status](https://travis-ci.org/rrrene/inch.png)](https://travis-ci.org/rrrene/inch)
2
2
 
3
- [![Build Status](https://travis-ci.org/rrrene/inch.png)](https://travis-ci.org/rrrene/inch)
3
+ Take a look at the project page for an [introduction with screenshots (live and in full color)](http://rrrene.github.io/inch/).
4
4
 
5
- Inch is a documentation measurement tool for Ruby, based on
6
- [YARD](http://yardoc.org/).
5
+ Inch is a documentation measurement tool for the Ruby programming language
6
+ that gives you hints where to improve your docs. One Inch at a time.
7
7
 
8
- It does not measure *coverage*, but gives you hints where to improve your
9
- docs. One Inch at a time.
10
8
 
11
9
 
12
10
  ## Installation
@@ -24,6 +22,7 @@ Or install it yourself as:
24
22
  $ gem install inch
25
23
 
26
24
 
25
+
27
26
  ## Usage
28
27
 
29
28
  To run Inch, simply type
data/TODOS.md CHANGED
@@ -7,3 +7,10 @@
7
7
  visibility options
8
8
  * Add support for multiple signatures for methods
9
9
  (realized via the @overload tag in YARD)
10
+ * Think about implicit cases in terms of evaluation:
11
+ * constructors without docstring/return_type
12
+ * ?-methods with a return description
13
+ * Think about limiting the number of `B`-objects in `inch suggest`
14
+ `inch suggest` shows too many `B`s even though there are still undocumented
15
+ objects in the codebase. this becomes a problem, when one thinks of `B` as
16
+ "good enough", which Inch itself suggests.
@@ -1,8 +1,21 @@
1
1
  module Inch
2
2
  module CLI
3
+ # Arguments parses given command-line arguments into the categories
4
+ # +files+, +object_names+, and +switches+.
5
+ #
6
+ # @example
7
+ #
8
+ # args = ["lib/*.rb", "README", "Foo", "Foo::Bar", "--color", "--all"]
9
+ # arguments = ::Inch::CLI::Arguments.new(args)
10
+ #
11
+ # arguments.files # => ["lib/*.rb", "README"]
12
+ # arguments.object_names # => ["Foo", "Foo::Bar"]
13
+ # arguments.switches # => ["--color", "--all"]
14
+ #
3
15
  class Arguments
4
16
  attr_reader :files, :object_names, :switches
5
17
 
18
+ # @param args [Array<String>]
6
19
  def initialize(args)
7
20
  @files = []
8
21
  @object_names = []
@@ -12,8 +25,10 @@ module Inch
12
25
 
13
26
  private
14
27
 
28
+ # @param args [Array<String>]
29
+ # @return [void]
15
30
  def parse(args)
16
- if first_non_file = args.find_index { |e| !file_or_glob?(e) }
31
+ if first_non_file = args.find_index { |e| !glob_or_file?(e) }
17
32
  @files = args[0...first_non_file]
18
33
  rest = args[first_non_file..-1]
19
34
  if first_switch = rest.find_index { |e| switch?(e) }
@@ -29,7 +44,17 @@ module Inch
29
44
  end
30
45
  end
31
46
 
32
- def file_or_glob?(f)
47
+ # Returns +true+ if a given String is a glob or a filename
48
+ #
49
+ # @example
50
+ #
51
+ # glob_or_file?("lib/*.rb") # => true
52
+ # glob_or_file?("README") # => true
53
+ # glob_or_file?("--help") # => false
54
+ #
55
+ # @param f [String]
56
+ # @return [Boolean]
57
+ def glob_or_file?(f)
33
58
  if f =~ /[\*\{]/
34
59
  true
35
60
  else
@@ -37,6 +62,15 @@ module Inch
37
62
  end
38
63
  end
39
64
 
65
+ # Returns +true+ if a given String is an option switch
66
+ #
67
+ # @example
68
+ #
69
+ # switch?("--help") # => true
70
+ # switch?("README") # => false
71
+ #
72
+ # @param f [String]
73
+ # @return [Boolean]
40
74
  def switch?(f)
41
75
  f =~ /^\-/
42
76
  end
@@ -1,19 +1,49 @@
1
1
  module Inch
2
2
  module CLI
3
+ # The classes in the Command namespace are controller objects for the
4
+ # command-line interface.
5
+ #
6
+ # A Command object is run via the class method +run+ (see {Base.run}).
7
+ # Its parameters are the command-line arguments (typically ARGV).
8
+ #
9
+ # A Command object utilizes an {Options} object to interpret the command-
10
+ # line arguments, then processes files and/or objects and finally uses an
11
+ # {Output} object to present the results to the user.
12
+ #
13
+ #
14
+ # To create a new command +Foo+ you must first subclass any of
15
+ #
16
+ # * Command::Base
17
+ # * Command::BaseList
18
+ # * Command::BaseObject
19
+ #
20
+ # Then you have to subclass Options and Output
21
+ # classes as well, to finally get something like this:
22
+ #
23
+ # * Command::Foo
24
+ # * Command::Options::Foo
25
+ # * Command::Output::Foo
26
+ #
27
+ # For an example, take a look at the Suggest command.
28
+ #
29
+ # @see Inch::CLI::Command::Suggest
30
+ # @see Inch::CLI::Command::Options::Suggest
31
+ # @see Inch::CLI::Command::Output::Suggest
3
32
  module Command
4
- # Abstract base class for CLI utilities. Provides some helper methods for
5
- # the option parser
33
+ # Abstract base class for CLI controller objects
6
34
  #
7
- # @abstract
8
- # @note This was adapted from YARD.
9
- # @see https://github.com/lsegal/yard/blob/master/lib/yard/cli/command.rb
35
+ # @abstract Subclass and override #run to implement a new command
36
+ # @note This was adapted from YARD
37
+ # https://github.com/lsegal/yard/blob/master/lib/yard/cli/command.rb
10
38
  class Base
11
39
  include TraceHelper
12
40
 
13
- attr_reader :source_parser
41
+ attr_reader :source_parser # @return [SourceParser]
14
42
 
15
- # Helper method to run the utility on an instance.
43
+ # Helper method to run an instance with the given +args+
44
+ #
16
45
  # @see #run
46
+ # @return [Command::Base] the instance that ran
17
47
  def self.run(*args)
18
48
  command = new
19
49
  command.run(*args)
@@ -27,13 +57,15 @@ module Inch
27
57
  end
28
58
 
29
59
  # Returns a description of the command
60
+ #
30
61
  # @return [String]
31
62
  def description
32
63
  ""
33
64
  end
34
65
 
35
66
  # Returns the name of the command by which it is referenced
36
- # in the command list.
67
+ # in the command list
68
+ #
37
69
  # @return [String]
38
70
  def name
39
71
  CommandParser.commands.each do |name, klass|
@@ -41,7 +73,17 @@ module Inch
41
73
  end
42
74
  end
43
75
 
76
+ # Runs the command with the given +args+
77
+ #
78
+ # @abstract
79
+ # @note Override with implementation
80
+ # @param *args [Array<String>]
81
+ def run(*args)
82
+ raise NotImplementedError
83
+ end
84
+
44
85
  # Returns a description of the command's usage pattern
86
+ #
45
87
  # @return [String]
46
88
  def usage
47
89
  "Usage: inch #{name} [options]"
@@ -49,6 +91,12 @@ module Inch
49
91
 
50
92
  private
51
93
 
94
+ # Returns the source parser against the given +paths+, while
95
+ # excluding all paths given in +excluded+
96
+ #
97
+ # @param paths [Array<String>]
98
+ # @param excluded [Array<String>]
99
+ # @return [void]
52
100
  def run_source_parser(paths, excluded)
53
101
  debug "Parsing:\n" \
54
102
  " files: #{paths.inspect}\n" \
@@ -1,6 +1,14 @@
1
1
  module Inch
2
2
  module CLI
3
3
  module Command
4
+ # Base class for Command objects concerned with lists of objects
5
+ #
6
+ # Commands subclassing from this class are called with an optional list
7
+ # of paths in the form:
8
+ #
9
+ # $ inch COMMAND [paths] [options]
10
+ #
11
+ # @abstract
4
12
  class BaseList < Base
5
13
  attr_writer :objects
6
14
 
@@ -12,7 +20,7 @@ module Inch
12
20
  # Prepares the list of objects and ranges, parsing arguments and
13
21
  # running the source parser.
14
22
  #
15
- # @param [Array<String>] args the list of arguments.
23
+ # @param *args [Array<String>] the list of arguments.
16
24
  # @return [void]
17
25
  def prepare_list(*args)
18
26
  @options.parse(args)
@@ -25,7 +33,7 @@ module Inch
25
33
  private
26
34
 
27
35
  # Assigns the objects returned by {#objects} to the score ranges in
28
- # @ranges based on their score
36
+ # +@ranges+ based on their score
29
37
  #
30
38
  def assign_objects_to_ranges
31
39
  @ranges.each do |range|
@@ -34,6 +42,9 @@ module Inch
34
42
  end
35
43
  end
36
44
 
45
+ # Filters the +@objects+ based on the settings in +@options+
46
+ #
47
+ # @return [void]
37
48
  def filter_objects
38
49
  if @options.namespaces == :only
39
50
  self.objects = objects.select(&:namespace?)
@@ -48,7 +59,7 @@ module Inch
48
59
  self.objects = objects.reject(&:undocumented?)
49
60
  end
50
61
  if @options.depth
51
- self.objects = objects.select { |o| o.depth <= @depth }
62
+ self.objects = objects.select { |o| o.depth <= @options.depth }
52
63
  end
53
64
  self.objects = objects.select do |o|
54
65
  @options.visibility.include?(o.visibility)
@@ -60,10 +71,13 @@ module Inch
60
71
  end
61
72
  end
62
73
 
74
+ # @return [Array<CodeObject::Proxy::Base>]
63
75
  def objects
64
76
  @objects ||= sort_by_priority(source_parser.all_objects)
65
77
  end
66
78
 
79
+ # @param objects [Array<CodeObject::Proxy::Base>]
80
+ # @return [Array<CodeObject::Proxy::Base>]
67
81
  def sort_by_priority(objects)
68
82
  objects.sort_by do |o|
69
83
  [o.priority, o.score, o.path.size]
@@ -1,6 +1,15 @@
1
1
  module Inch
2
2
  module CLI
3
3
  module Command
4
+ # Base class for Command objects concerned with clearly specified
5
+ # objects.
6
+ #
7
+ # Commands subclassing from this class are called with a list of object
8
+ # names (most commonly only one) in the form:
9
+ #
10
+ # $ inch COMMAND [paths] OBJECT_NAME [, OBJECT_NAME2, ...] [options]
11
+ #
12
+ # @abstract
4
13
  class BaseObject < Base
5
14
  attr_accessor :object, :objects
6
15
 
@@ -9,23 +18,27 @@ module Inch
9
18
  @ranges = Evaluation.new_score_ranges
10
19
  end
11
20
 
12
- # Prepares the (list of) objects, parsing arguments and
21
+ # Prepares the given objects, parsing arguments and
13
22
  # running the source parser.
14
23
  #
15
- # @param [Array<String>] args the list of arguments.
24
+ # @param *args [Array<String>] the list of arguments
16
25
  # @return [void]
17
26
  def prepare_objects(*args)
18
27
  @options.parse(args)
19
28
  @options.verify
20
29
  run_source_parser(@options.paths, @options.excluded)
21
30
 
22
- self.objects = find_object_names(@options.object_names)
31
+ self.objects = find_objects_with_names(@options.object_names)
23
32
  self.object = @objects.first
24
33
  end
25
34
 
26
35
  private
27
36
 
28
- def find_object_names(object_names)
37
+ # Returns all objects matching the given +object_names+
38
+ #
39
+ # @param object_names [Array<String>]
40
+ # @return [Array<CodeObject::Proxy::Base>]
41
+ def find_objects_with_names(object_names)
29
42
  object_names.map do |object_name|
30
43
  if object = source_parser.find_object(object_name)
31
44
  object
@@ -3,15 +3,29 @@ require 'optparse'
3
3
  module Inch
4
4
  module CLI
5
5
  module Command
6
+ # The classes in the Command::Options namespace are concerned with
7
+ # parsing of command-line arguments via OptionParser and converting
8
+ # these arguments into instance attributes.
9
+ #
10
+ # These attributes are then read and interpreted by the Command object.
11
+ #
12
+ # @see Inch::CLI::Command::Suggest
13
+ # @see Inch::CLI::Command::Options::Suggest
6
14
  module Options
7
15
  # Abstract base class for CLI options. Provides some helper methods for
8
- # the option parser
16
+ # the option parser.
9
17
  #
18
+ # @abstract Subclass and override #set_options
10
19
  class Base
11
20
  include TraceHelper
12
21
  include YardoptsHelper
13
22
 
14
23
  class << self
24
+ # Creates an attribute with an optional default value
25
+ #
26
+ # @param name [Symbol] the name of the attribute
27
+ # @param default [nil] the default value of the attribute
28
+ # @return [void]
15
29
  def attribute(name, default = nil)
16
30
  define_method(name) do
17
31
  instance_variable_get("@#{name}") || default
@@ -22,10 +36,14 @@ module Inch
22
36
  end
23
37
  end
24
38
 
25
- attribute :usage, ""
26
- attribute :paths, []
27
- attribute :excluded, []
39
+ attribute :usage, "" # usage description for the command
40
+ attribute :paths, [] # the paths of the to-be-analysed sources
41
+ attribute :excluded, [] # paths to be excluded from the analysis
28
42
 
43
+ # Parses the given +args+ "into" the current Options object
44
+ #
45
+ # @param args [Array<String>] command-line arguments
46
+ # @return [void]
29
47
  def parse(args)
30
48
  opts = OptionParser.new
31
49
  opts.banner = usage
@@ -38,29 +56,51 @@ module Inch
38
56
  parse_options(opts, args)
39
57
  end
40
58
 
59
+ # Sets all options for the current Options object
60
+ #
61
+ # @note Override to fill with individual options
62
+ #
63
+ # @param opts [OptionParser]
64
+ # @return [void]
41
65
  def set_options(opts)
42
66
  common_options(opts)
43
67
  end
44
68
 
45
- # Override and fill with validations
69
+ # Verifies if the given options are valid
70
+ #
71
+ # @note Override to fill with validations
72
+ #
73
+ # @return [void]
46
74
  def verify
47
75
  end
48
76
 
49
77
  protected
50
78
 
51
- # Override and fill with an array of descriptions that will be
52
- # shown via the help switch.
79
+ # Returns an array of descriptions that will be shown via the
80
+ # +--help+ switch
81
+ #
82
+ # @note Override to fill with an array of descriptions
83
+ #
84
+ # @return [Array<String>]
53
85
  def descriptions
54
86
  []
55
87
  end
56
88
 
57
- def description_arrows
89
+ # Returns a decriptive hint explaining the arrows used to represent
90
+ # code object priorities
91
+ #
92
+ # @return [String]
93
+ def description_hint_arrows
58
94
  arrows = Output::Base::PRIORITY_ARROWS.join(' ')
59
95
  "Arrows (#{arrows}) hint at the importance of the object " +
60
96
  "being documented."
61
97
  end
62
98
 
63
- def description_grades
99
+ # Returns a decriptive hint explaining the arrows used to represent
100
+ # code object grades
101
+ #
102
+ # @return [String]
103
+ def description_hint_grades
64
104
  grades = Evaluation.new_score_ranges.map(&:grade)
65
105
  "School grades (#{grades.join(', ')}) are assigned and " +
66
106
  "displayed with each object."
@@ -68,8 +108,8 @@ module Inch
68
108
 
69
109
  DEFAULT_PATHS = ["{lib,app}/**/*.rb", "ext/**/*.c"]
70
110
 
71
- # @yard_files is assigned by YardoptsHelper#parse_yardopts_options
72
111
  def get_paths(args)
112
+ # @yard_files is assigned by YardoptsHelper#parse_yardopts_options
73
113
  paths = @yard_files ? @yard_files : args.dup
74
114
  if paths.empty?
75
115
  DEFAULT_PATHS
@@ -98,6 +138,10 @@ module Inch
98
138
  end
99
139
  end
100
140
 
141
+ # Quits the application using `exit`
142
+ #
143
+ # @param msg [String,nil] optional, message to be displayed
144
+ # @return [void]
101
145
  def kill(msg = nil)
102
146
  warn usage
103
147
  warn msg.red unless msg.nil?
@@ -118,6 +162,7 @@ module Inch
118
162
  kill unrecognized_option(err)
119
163
  end
120
164
 
165
+ # Resets the command-line interface before each run
121
166
  def reset
122
167
  # color is enabled by default, can be turned of by switch --no-color
123
168
  Term::ANSIColor::coloring = true