inch 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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