peeky 0.0.39 → 0.0.45

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3247c282a72d505136e9a837dfc2b834b793234fafac57d34abf01845d3573cb
4
- data.tar.gz: 7687ce409a954be8b01462f707bb08f8724ed5fee649203a1ddbc3a5d22802d8
3
+ metadata.gz: b59687793d9f01e4a7c6f0db2e1fdd8e20b614446815c82f13decabf5661704b
4
+ data.tar.gz: d49b1a2a72414094caff610f371fa242688e78b07f91edb38d7565a9aa5f650c
5
5
  SHA512:
6
- metadata.gz: 4bdaba25fa466a29378293696530be6f8e7630e45e9d37c77016e0fe09fc5e0712b411a3c70627a21dae7e439c82d66465c09f3b08607534dbb0650ae7dd2185
7
- data.tar.gz: 32a64cf623e9056e47a66861a541199d6144efdbf2551341cd4d770cce51962f4b3f5c840bda0b1d3c8545476f66c74885d7b530617246a0a4a97dfe3773f3fd
6
+ metadata.gz: 15d8633c3f3e3e917161c4b6acaa40e16cf3a6c58fb4cbeb2c4bfb00c8f3f168e81092aa8ecd397fedcba521a4b9a58a4101e9fa70598b20e1c623f4f27c3636
7
+ data.tar.gz: cf82156956b67d6b90f467ce816418cd9a56fcc05e0f98bd5c96e29fe448fde7727420489114651fdaab89c27a004759bf8508d79c4f15fafdfbebe1e59b3421
data/.rubocop.yml CHANGED
@@ -5,7 +5,7 @@ AllCops:
5
5
  NewCops: enable
6
6
  Exclude:
7
7
  - "_/**/*"
8
- - "lib/peeky/example/yard_sample.rb"
8
+ - "spec/sample/**/*"
9
9
 
10
10
  # My Preferences - Start
11
11
  Metrics/ClassLength:
data/Guardfile CHANGED
@@ -23,7 +23,7 @@ group :green_pass_then_cop, halt_on_fail: true do
23
23
  watch(%r{^lib/peeky/commands/(.+)\.rb$}) { |m| "spec/unit/commands/#{m[1]}_spec.rb" }
24
24
  end
25
25
 
26
- guard :rubocop, all_on_start: false, cli: ['--format', 'clang'] do
26
+ guard :rubocop, all_on_start: false, cli: ['--format', 'clang', '-a'] do
27
27
  watch(%r{.+\.rb$})
28
28
  watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
29
29
  end
data/README.md CHANGED
@@ -4,6 +4,10 @@
4
4
 
5
5
  When using the source code for this gem, start by running `bin/setup` to install locally or `bundle install`
6
6
 
7
+ ## TODO
8
+
9
+ @klueless-io - look at [show-source](https://stackoverflow.com/questions/13012109/get-class-location-from-class-object)
10
+
7
11
  ## Installation
8
12
 
9
13
  Add this line to your application's Gemfile:
data/Rakefile CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ GEM_NAME = 'peeky'
4
+
3
5
  require 'bundler/gem_tasks'
4
6
  require 'rspec/core/rake_task'
5
7
 
@@ -14,3 +16,16 @@ Rake::ExtensionTask.new('peeky') do |ext|
14
16
  end
15
17
 
16
18
  task default: %i[clobber compile spec]
19
+
20
+ desc 'Publish the gem to RubyGems.org'
21
+ task :publish do
22
+ system 'gem build'
23
+ system "gem push #{GEM_NAME}-#{Peeky::VERSION}.gem"
24
+ end
25
+
26
+ desc 'Remove old *.gem files'
27
+ task :clean do
28
+ system 'rm *.gem'
29
+ end
30
+
31
+ task default: %i[clobber compile spec]
@@ -26,16 +26,23 @@ module Peeky
26
26
  else
27
27
  result.push kv('# of instance methods', '')
28
28
  end
29
- if defined?(@_signatures)
29
+ if defined?(@signatures)
30
30
  result.push kv('# of accessors', accessors.length)
31
31
  result.push kv('# of readers', readers.length)
32
32
  result.push kv('# of writers', writers.length)
33
- result.push kv('# of methods', methods.length)
33
+ result.push kv('# of methods', all_methods.length)
34
+ result.push kv('# of methods - public', public_methods.length)
35
+ result.push kv('# of methods - private', private_methods.length)
36
+ result.push kv('# of class methods', class_methods.length)
37
+
34
38
  else
35
- result.push kv('# of accessors', '')
36
- result.push kv('# of readers', '')
37
- result.push kv('# of writers', '')
38
- result.push kv('# of methods', '')
39
+ result.push 'Not Loaded'
40
+ # result.push kv('# of accessors', '')
41
+ # result.push kv('# of readers', '')
42
+ # result.push kv('# of writers', '')
43
+ # result.push kv('# of methods', '')
44
+ # result.push kv('# of methods - public', '')
45
+ # result.push kv('# of methods - private', '')
39
46
  end
40
47
  result.join("\n")
41
48
  end
@@ -49,8 +56,6 @@ module Peeky
49
56
  # At times during debug or other edge cases, it may be useful to
50
57
  # pre-load this information early.
51
58
  def load
52
- ruby_instance_methods
53
- ruby_instance_method_names
54
59
  signatures
55
60
  end
56
61
 
@@ -61,19 +66,19 @@ module Peeky
61
66
 
62
67
  # Class name
63
68
  def class_name
64
- @_class_name ||= class_full_name.to_s.gsub(/^.*::/, '')
69
+ @class_name ||= class_full_name.to_s.gsub(/^.*::/, '')
65
70
  # instance.class.name.split('::').last
66
71
  end
67
72
 
68
73
  # Module name
69
74
  def module_name
70
- @_module_name ||= class_full_name.to_s.gsub(/(.*)::.*/, '\1')
75
+ @module_name ||= class_full_name.to_s.gsub(/(.*)::.*/, '\1')
71
76
  end
72
77
 
73
78
  # Get a list of :attr_accessor on the class
74
79
  # @return [Array<AttrInfo>] list of AttrInfo where type is :attr_accessor
75
80
  def accessors
76
- @_accessors ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_accessor }
81
+ @accessors ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_accessor }
77
82
  end
78
83
 
79
84
  # Get a list of :attr_accessors ordered the way they are in the source code
@@ -86,7 +91,7 @@ module Peeky
86
91
 
87
92
  # Attribute infos
88
93
  def attribute_infos
89
- @_attribute_infos ||= begin
94
+ @attribute_infos ||= begin
90
95
  grouped_method_infos = signatures.select { |signature| signature.readable? || signature.writable? }.group_by(&:clean_name)
91
96
 
92
97
  grouped_method_infos.keys.map { |key| AttrInfo.create(*grouped_method_infos[key]) }
@@ -102,8 +107,26 @@ module Peeky
102
107
 
103
108
  # Get a list methods
104
109
  # @return [Array<MethodInfo>] list of MethodInfo where type is :method
105
- def methods
106
- @_methods ||= signatures.select { |signature| signature.implementation_type == :method }
110
+ def all_methods
111
+ @all_methods ||= signatures.select { |signature| signature.implementation_type == :method }
112
+ end
113
+
114
+ # Get a list of private methods
115
+ # @return [Array<MethodInfo>] list of MethodInfo where type is :method
116
+ def private_methods
117
+ @private_methods ||= signatures.select { |signature| signature.implementation_type == :method && signature.access_control == :private }
118
+ end
119
+
120
+ # Get a list of public methods
121
+ # @return [Array<MethodInfo>] list of MethodInfo where type is :method
122
+ def public_methods
123
+ @public_methods ||= signatures.select { |signature| signature.implementation_type == :method && signature.access_control == :public }
124
+ end
125
+
126
+ # Get a list of class methods
127
+ # @return [Array<MethodInfo>] list of MethodInfo where type is :method
128
+ def class_methods
129
+ @class_methods ||= signatures.select { |signature| signature.implementation_type == :class_method }
107
130
  end
108
131
 
109
132
  # Get a list methods ordered the way they are in the source code
@@ -111,7 +134,7 @@ module Peeky
111
134
  def methods_source_order
112
135
  # TODO: This feature is required
113
136
  # May be best to have a sort object that can be created for each type of ordering that is needed
114
- methods
137
+ all_methods
115
138
  end
116
139
 
117
140
  # Reader by name
@@ -124,7 +147,7 @@ module Peeky
124
147
  # Get a list of :attr_reader on the class
125
148
  # @return [Array<AttrInfo>] list of AttrInfo where type is :attr_accessor
126
149
  def readers
127
- @_readers ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_reader }
150
+ @readers ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_reader }
128
151
  end
129
152
 
130
153
  # Get a list of :attr_reader ordered the way they are in the source code
@@ -138,7 +161,7 @@ module Peeky
138
161
  # Get a list of :attr_writer on the class
139
162
  # @return [Array<AttrInfo>] list of AttrInfo where type is :attr_writer
140
163
  def writers
141
- @_writers ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_writer }
164
+ @writers ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_writer }
142
165
  end
143
166
 
144
167
  # Get a list of :attr_writer ordered the way they are in the source code
@@ -161,7 +184,14 @@ module Peeky
161
184
  # such as static, private vs public
162
185
  # deep, deep_to_level, this_instance.
163
186
  def signatures
164
- @_signatures ||= ruby_instance_methods.map { |im| MethodInfo.new(im, @instance) }
187
+ return @signatures if defined? @signatures
188
+
189
+ @signatures = begin
190
+ instance_methods = ruby_instance_methods.map { |im| MethodInfo.new(im, @instance) }
191
+ private_methods = ruby_private_methods.map { |im| MethodInfo.new(im, @instance, access_control: :private) }
192
+ class_methods = ruby_class_methods.map { |im| MethodInfo.new(im, @instance, implementation_type: :class_method) }
193
+ instance_methods + private_methods + class_methods
194
+ end
165
195
  end
166
196
 
167
197
  # Signatures by clean name
@@ -187,13 +217,36 @@ module Peeky
187
217
  "#{key.to_s.ljust(25)}: #{value}"
188
218
  end
189
219
 
220
+ def ruby_class_method_names
221
+ @ruby_class_method_names ||= instance.class.singleton_class.instance_methods(false).sort
222
+ end
223
+
190
224
  def ruby_instance_method_names
191
- @_ruby_instance_method_names ||= instance.class.instance_methods(false).sort
225
+ @ruby_instance_method_names ||= instance.class.instance_methods(false).sort
226
+ end
227
+
228
+ def ruby_private_method_names
229
+ @ruby_private_method_names ||= instance.private_methods(false).sort
230
+ end
231
+
232
+ def ruby_class_methods
233
+ @ruby_class_methods ||= ruby_class_method_names.map { |method_name| instance.class.method(method_name) }
234
+ rescue StandardError => e
235
+ # puts 'ruby_class_methods'
236
+ puts e
237
+ end
238
+
239
+ def ruby_private_methods
240
+ @ruby_private_methods ||= ruby_private_method_names.map { |method_name| instance.method(method_name) }
241
+ rescue StandardError => e
242
+ # puts 'ruby_private_methods'
243
+ puts e
192
244
  end
193
245
 
194
246
  def ruby_instance_methods
195
- @_ruby_instance_methods ||= ruby_instance_method_names.map { |method_name| instance.method(method_name) }
247
+ @ruby_instance_methods ||= ruby_instance_method_names.map { |method_name| instance.method(method_name) }
196
248
  rescue StandardError => e
249
+ # puts 'ruby_instance_methods'
197
250
  puts e
198
251
  end
199
252
  end
@@ -14,26 +14,29 @@ module Peeky
14
14
  # MethodInfo delegates to the underlying ruby method object
15
15
  attr_reader :focal_method
16
16
 
17
+ attr_reader :access_control
18
+
17
19
  def_delegators :focal_method, :name, :receiver, :arity, :super_method
18
20
 
19
21
  ## Stage 2 is the method likely to be an attribute reader or writer
20
22
  #
21
23
 
22
24
  # Implementation type indicates the probable representation of this
23
- # method in ruby, was it `def method` or `attr_reader` / `attr_writer`
25
+ # method in ruby, was it
26
+ # instance method `def method`
27
+ # instance method reader `attr_reader`
28
+ # instance method writer `attr_writer`
29
+ # class method `def self.method`
24
30
  attr_reader :implementation_type
25
31
 
26
- def initialize(method, target_instance)
32
+ def initialize(method, target_instance, implementation_type: :method, access_control: :public)
27
33
  @focal_method = method
28
34
  @target_instance = target_instance
35
+ @access_control = access_control
36
+ @implementation_type = implementation_type
29
37
  @parameters = ParameterInfo.from_method(method)
30
- # stage 1
31
- # @implementation_type = :method
32
38
 
33
- # stage 2
34
39
  infer_implementation_type
35
-
36
- # stage 3
37
40
  infer_default_paramaters
38
41
  end
39
42
 
@@ -52,20 +55,13 @@ module Peeky
52
55
  end
53
56
  end
54
57
 
55
- # Infer implementation type [:method, :attr_reader or :attr_writer]
56
- # rubocop:disable Lint/DuplicateBranch
58
+ # Infer implementation type [:class_method, :method, :attr_reader or :attr_writer]
57
59
  def infer_implementation_type
58
- @implementation_type = if @target_instance.nil?
59
- :method
60
- elsif match(Peeky::Predicates::AttrReaderPredicate)
61
- :attr_reader
62
- elsif match(Peeky::Predicates::AttrWriterPredicate)
63
- :attr_writer
64
- else
65
- :method
66
- end
60
+ return unless @implementation_type == :method
61
+
62
+ @implementation_type = :attr_reader if match(Peeky::Predicates::AttrReaderPredicate)
63
+ @implementation_type = :attr_writer if match(Peeky::Predicates::AttrWriterPredicate)
67
64
  end
68
- # rubocop:enable Lint/DuplicateBranch
69
65
 
70
66
  # Get parameter by name
71
67
  #
@@ -92,13 +88,16 @@ module Peeky
92
88
  # The tests are now down to 5 seconds, but it highlights the cost of use
93
89
  # TracePoint.
94
90
  def infer_default_paramaters
95
- minimalist_method = Peeky::Renderer::MethodCallMinimumParamsRender.new(self).render
91
+ class_name = @implementation_type == :class_method ? @target_instance.class.name : nil
92
+ minimalist_method = Peeky::Renderer::MethodCallMinimumParamsRender.new(self, class_name: class_name).render
96
93
 
97
94
  return if minimalist_method.end_with?('=')
98
95
  return unless optional?
99
96
 
100
97
  tracer.enable do
101
- @target_instance.instance_eval(minimalist_method)
98
+ # TODO: minimalist method should be able to handle class methods
99
+ @target_instance.instance_eval(minimalist_method) if @implementation_type == :method
100
+ @target_instance.class.instance_eval(minimalist_method) if @implementation_type == :class_method
102
101
  rescue StandardError => e
103
102
  # just print the error for now, we are only attempting to capture the
104
103
  # first call, any errors inside the call cannot be dealt with and should
@@ -32,7 +32,12 @@ module Peeky
32
32
  cloned = instance.clone
33
33
 
34
34
  cloned.instance_eval(code)
35
- current_value = cloned.send(method_name)
35
+ begin
36
+ current_value = cloned.send(method_name)
37
+ rescue StandardError #=> exception
38
+ current_value = nil
39
+ end
40
+
36
41
  current_value == new_value
37
42
  end
38
43
 
@@ -24,13 +24,9 @@ module Peeky
24
24
  output.push('')
25
25
  end
26
26
 
27
- methods = render_methods
28
-
29
- if methods.length.positive?
30
- output.push("-- Public Methods #{'-' * 82}")
31
- output.push(*methods)
32
- output.push('')
33
- end
27
+ render_methods_with_heading(output, @class_info.public_methods, 'Public Methods')
28
+ render_methods_with_heading(output, @class_info.class_methods, 'Class Methods')
29
+ render_methods_with_heading(output, @class_info.private_methods, 'Private Methods')
34
30
 
35
31
  output.pop if output.last == ''
36
32
 
@@ -70,10 +66,20 @@ module Peeky
70
66
  @class_info.writers.map { |attr| kv('attr_writer', attr.name) }
71
67
  end
72
68
 
73
- def render_methods
74
- @class_info.methods.flat_map do |method|
69
+ def render_methods_with_heading(output, method_list, heading)
70
+ methods = render_methods(method_list)
71
+
72
+ return unless methods.length.positive?
73
+
74
+ output.push("-- #{heading} #{'-' * 82}")
75
+ output.push(*methods)
76
+ output.push('')
77
+ end
78
+
79
+ def render_methods(method_list)
80
+ method_list.flat_map do |method|
75
81
  [
76
- "#{method.name}::",
82
+ "[ #{method.name} ]",
77
83
  *render_paramaters(method.parameters),
78
84
  ''
79
85
  ]
@@ -2,32 +2,44 @@
2
2
 
3
3
  module Peeky
4
4
  module Renderer
5
- # Render: Class Interface
5
+ # Render: Class Interface Example
6
6
  #
7
- # Example output:
8
- # class SampleClassClassInterfaceRender
9
- # attr_accessor :a
7
+ # class ComplexClass
8
+ # attr_accessor :a_read_write1
9
+ # attr_accessor :a_read_write2
10
+
11
+ # attr_reader :b_another_reader
12
+ # attr_reader :b_reader
13
+ # attr_reader :looks_like_an_attr_reader
14
+
15
+ # attr_writer :c_another_writer
16
+ # attr_writer :c_writer
17
+
18
+ # def alpha_sort1; end
19
+ # def alpha_sort2; end
20
+ # def destructive!; end
21
+ # def do_something_method; end
22
+ # def method_01(aaa); end
23
+ # def method_02(aaa, bbb = 1); end
24
+ # def method_03(aaa, bbb = 1, ccc = 2); end
25
+ # def method_04(*aaa); end
26
+ # def method_05(aaa, bbb = 1, *ccc); end
27
+ # def method_06(**aaa); end
28
+ # def method_07(aaa, *bbb, ccc: 'string1', **ddd); end
29
+ # def method_08(aaa, *bbb, **ccc, &ddd); end
30
+ # def method_09(aaa:); end
31
+ # def method_10(aaa:, bbb: 1); end
32
+ # def method_with_every_type_of_paramater(aaa, bbb = 1, *ccc, ddd:, eee: 1, **fff, &ggg);end
33
+ # def questionable?; end
10
34
  #
11
- # attr_reader :b
35
+ # class << self
36
+ # def klass_complex(aaa, bbb = nil, *ccc, ddd:, eee: , **fff, &ggg); end
37
+ # def klass_simple(first_param); end
38
+ # end
12
39
  #
13
- # attr_writer :c
40
+ # private
14
41
  #
15
- # def alpha_sort1; end
16
- # def alpha_sort2; end
17
- # def d; end
18
- # def e(aaa); end
19
- # def f(aaa, bbb = nil); end
20
- # def g(aaa, bbb = nil, ccc = nil); end
21
- # def h(*aaa); end
22
- # def i(aaa, bbb, *ccc); end
23
- # def j(**aaa); end
24
- # def k(aaa, *bbb, **ccc); end
25
- # def l(aaa, *bbb, **ccc, &ddd); end
26
- # def m(aaa:); end
27
- # def n(aaa:, bbb: nil); end
28
- # def p?; end
29
- # def q!; end
30
- # def z(aaa, bbb = nil, *ccc, ddd:, eee: nil, **fff, &ggg); end
42
+ # def keep_me_private; end
31
43
  # end
32
44
  class ClassInterfaceRender
33
45
  # ClassInfo with information about the class instance to be rendered.
@@ -40,19 +52,24 @@ module Peeky
40
52
  # Render the class interface
41
53
  def render
42
54
  @indent = ''
43
- output = []
44
- output.push render_start
55
+ @output = []
56
+ @output.push render_start
45
57
  @indent = ' '
46
- output += render_accessors
47
- output += render_readers
48
- output += render_writers
49
- output += render_methods
50
- output.pop if output.last == ''
58
+
59
+ render_accessors
60
+ render_readers
61
+ render_writers
62
+
63
+ render_methods(@class_info.public_methods)
64
+ render_class_methods(@class_info.class_methods)
65
+ render_private_methods(@class_info.private_methods)
66
+
67
+ @output.pop if @output.last == ''
51
68
 
52
69
  @indent = ''
53
- output.push render_end
70
+ @output.push render_end
54
71
 
55
- output.join("\n")
72
+ @output.join("\n")
56
73
  end
57
74
 
58
75
  private
@@ -64,28 +81,46 @@ module Peeky
64
81
  def render_accessors
65
82
  result = @class_info.accessors.map { |attr| "#{@indent}attr_accessor :#{attr.name}" }
66
83
  result.push '' unless result.length.zero?
67
- result
84
+ @output += result
68
85
  end
69
86
 
70
87
  def render_readers
71
88
  result = @class_info.readers.map { |attr| "#{@indent}attr_reader :#{attr.name}" }
72
89
  result.push '' unless result.length.zero?
73
- result
90
+ @output += result
74
91
  end
75
92
 
76
93
  def render_writers
77
94
  result = @class_info.writers.map { |attr| "#{@indent}attr_writer :#{attr.name}" }
78
95
  result.push '' unless result.length.zero?
79
- result
96
+ @output += result
80
97
  end
81
98
 
82
- def render_methods
83
- result = @class_info.methods.map do |method_signature|
99
+ def render_methods(method_list)
100
+ result = method_list.map do |method_signature|
84
101
  render_signature = Peeky::Renderer::MethodSignatureRender.new(method_signature)
85
102
  "#{@indent}#{render_signature.render}"
86
103
  end
87
104
  result.push '' unless result.length.zero?
88
- result
105
+ @output += result
106
+ end
107
+
108
+ def render_class_methods(methods)
109
+ return if methods.length.zero?
110
+
111
+ @output += ["#{@indent}class << self"]
112
+ @indent += ' '
113
+ @output += render_methods(methods)
114
+ @indent.delete_suffix!(' ')
115
+ @output.pop if @output.last == ''
116
+ @output += ["#{@indent}end", '']
117
+ end
118
+
119
+ def render_private_methods(methods)
120
+ return if methods.length.zero?
121
+
122
+ @output += ["#{@indent}private", '']
123
+ @output += render_methods(methods)
89
124
  end
90
125
 
91
126
  def render_end
@@ -33,26 +33,33 @@ module Peeky
33
33
 
34
34
  # Render the class interface with YARD documentation
35
35
  def render
36
- output = []
37
- output.push render_start
36
+ @output = []
37
+
38
+ render_start
38
39
  @indent += ' '
39
- output += (render_accessors + render_readers + render_writers + render_methods)
40
- output.pop if output.last == ''
40
+
41
+ render_accessors
42
+ render_readers
43
+ render_writers
44
+
45
+ render_public_methods
46
+ render_class_methods
47
+ render_private_methods
48
+
49
+ @output.pop if @output.last == ''
41
50
 
42
51
  @indent = @indent[0..-3]
43
52
 
44
- output.push render_end
53
+ @output.push render_end
45
54
 
46
- output.join("\n")
55
+ @output.join("\n")
47
56
  end
48
57
 
49
58
  private
50
59
 
51
60
  def render_start
52
- [
53
- "#{@indent}# #{@class_info.class_name.titleize.humanize}",
54
- "#{@indent}class #{@class_info.class_name}"
55
- ]
61
+ @output.push "#{@indent}# #{@class_info.class_name.titleize.humanize}"
62
+ @output.push "#{@indent}class #{@class_info.class_name}"
56
63
  end
57
64
 
58
65
  def render_accessors
@@ -63,7 +70,7 @@ module Peeky
63
70
  result.push "#{@indent}attr_accessor :#{attr.name}"
64
71
  end
65
72
  result.push '' unless result.length.zero?
66
- result
73
+ @output += result
67
74
  end
68
75
 
69
76
  def render_readers
@@ -74,7 +81,7 @@ module Peeky
74
81
  result.push "#{@indent}attr_reader :#{attr.name}"
75
82
  end
76
83
  result.push '' unless result.length.zero?
77
- result
84
+ @output += result
78
85
  end
79
86
 
80
87
  def render_writers
@@ -85,54 +92,81 @@ module Peeky
85
92
  result.push "#{@indent}attr_writer :#{attr.name}"
86
93
  end
87
94
  result.push '' unless result.length.zero?
88
- result
95
+ @output += result
89
96
  end
90
97
 
91
- # rubocop:disable Metrics/AbcSize, Metrics/BlockLength, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/MethodLength
92
- def render_methods
98
+ def render_public_methods
93
99
  result = []
94
- class_info.methods.map.with_index do |method_signature, index|
95
- result.push '' if index.positive?
96
- result.push "#{@indent}# #{method_signature.name.to_s.humanize}"
97
-
98
- method_signature.parameters.each_with_index do |parameter, param_index|
99
- result.push "#{@indent}#" if param_index.zero?
100
-
101
- case parameter.type
102
- when :splat
103
- result.push "#{@indent}# @param #{parameter.name} [Array<#{default_splat_param_type}>] *#{parameter.name} - list of #{parameter.name.to_s.humanize.downcase}"
104
- when :double_splat
105
- result.push "#{@indent}# @param #{parameter.name} [<key: value>...] **#{parameter.name} - list of key/values"
106
- when :block
107
- result.push "#{@indent}# @param #{parameter.name} [Block] &#{parameter.name}"
108
- when :key_required
109
- result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name}: <value for #{parameter.name.to_s.humanize.downcase}> (required)"
110
- when :key_optional
111
- result.push "#{@indent}# @param #{parameter.name} [#{parameter.default_value_type}] #{parameter.name}: is optional, defaults to #{parameter.wrap_default_value('nil')}"
112
- when :param_required
113
- result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase} (required)"
114
- when :param_optional
115
- result.push "#{@indent}# @param #{parameter.name} [#{parameter.default_value_type}] #{parameter.name} is optional, defaults to #{parameter.wrap_default_value('nil')}"
116
- # result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase} (optional)"
117
- else
118
- result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase}"
119
- end
120
- end
100
+ class_info.public_methods.map.with_index do |method_signature, index|
101
+ render_method(result, method_signature, index)
102
+ end
103
+ result.push '' unless result.length.zero?
104
+ @output += result
105
+ end
106
+
107
+ def render_class_methods
108
+ return if class_info.class_methods.length.zero?
109
+
110
+ result = ["#{@indent}# Class methods", "#{@indent}class << self"]
111
+ @indent += ' '
112
+ class_info.class_methods.map.with_index do |method_signature, index|
113
+ render_method(result, method_signature, index)
114
+ end
115
+ @indent.delete_suffix!(' ')
116
+ result.push "#{@indent}end"
117
+
118
+ @output += result
119
+ end
121
120
 
122
- if method_signature.name.to_s.end_with?('?')
123
- result.push ''
124
- result.push "#{@indent}# @return [Boolean] true when #{method_signature.name.to_s.humanize.downcase}"
121
+ def render_private_methods
122
+ result = []
123
+ class_info.private_methods.map.with_index do |method_signature, index|
124
+ result.push "\n#{indent}private\n" if index.zero?
125
+ render_method(result, method_signature, index)
126
+ end
127
+ @output += result
128
+ end
129
+
130
+ # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
131
+ def render_method(result, method_signature, index)
132
+ result.push '' if index.positive?
133
+ result.push "#{@indent}# #{method_signature.name.to_s.humanize}"
134
+
135
+ method_signature.parameters.each_with_index do |parameter, param_index|
136
+ result.push "#{@indent}#" if param_index.zero?
137
+
138
+ case parameter.type
139
+ when :splat
140
+ result.push "#{@indent}# @param #{parameter.name} [Array<#{default_splat_param_type}>] *#{parameter.name} - list of #{parameter.name.to_s.humanize.downcase}"
141
+ when :double_splat
142
+ result.push "#{@indent}# @param #{parameter.name} [<key: value>...] **#{parameter.name} - list of key/values"
143
+ when :block
144
+ result.push "#{@indent}# @param #{parameter.name} [Block] &#{parameter.name}"
145
+ when :key_required
146
+ result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name}: <value for #{parameter.name.to_s.humanize.downcase}> (required)"
147
+ when :key_optional
148
+ result.push "#{@indent}# @param #{parameter.name} [#{parameter.default_value_type}] #{parameter.name}: is optional, defaults to #{parameter.wrap_default_value('nil')}"
149
+ when :param_required
150
+ result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase} (required)"
151
+ when :param_optional
152
+ result.push "#{@indent}# @param #{parameter.name} [#{parameter.default_value_type}] #{parameter.name} is optional, defaults to #{parameter.wrap_default_value('nil')}"
153
+ # result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase} (optional)"
154
+ else
155
+ result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase}"
125
156
  end
157
+ end
126
158
 
127
- render_signature = Peeky::Renderer::MethodSignatureRender.new(method_signature)
128
- render_signature.indent = @indent
129
- render_signature.style = :default
130
- result.push render_signature.render
159
+ if method_signature.name.to_s.end_with?('?')
160
+ result.push ''
161
+ result.push "#{@indent}# @return [Boolean] true when #{method_signature.name.to_s.humanize.downcase}"
131
162
  end
132
- result.push '' unless result.length.zero?
133
- result
163
+
164
+ render_signature = Peeky::Renderer::MethodSignatureRender.new(method_signature)
165
+ render_signature.indent = @indent
166
+ render_signature.style = :default
167
+ result.push render_signature.render
134
168
  end
135
- # rubocop:enable Metrics/AbcSize, Metrics/BlockLength, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/MethodLength
169
+ # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
136
170
 
137
171
  def render_end
138
172
  "#{@indent}end"
@@ -13,7 +13,8 @@ module Peeky
13
13
 
14
14
  def initialize(method_signature, **opts)
15
15
  # instance_name = opts[:instance_name] || 'instance'
16
- @instance_name = opts[:instance_name]
16
+ @instance_name = opts[:instance_name]
17
+ @class_name = opts[:class_name]
17
18
  @method_signature = method_signature
18
19
  end
19
20
 
@@ -29,11 +30,10 @@ module Peeky
29
30
 
30
31
  params = minimal_call_parameters.length.zero? ? '' : "(#{minimal_call_parameters})"
31
32
 
32
- if @instance_name.nil?
33
- "#{name}#{params}"
34
- else
35
- "#{@instance_name}.#{name}#{params}"
36
- end
33
+ return "#{@instance_name}.#{name}#{params}" unless @instance_name.nil?
34
+ return "#{@class_name}.#{name}#{params}" unless @class_name.nil?
35
+
36
+ "#{name}#{params}"
37
37
  end
38
38
  end
39
39
  end
data/lib/peeky/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Peeky
4
- VERSION = '0.0.39'
4
+ VERSION = '0.0.45'
5
5
  end
data/lib/peeky.rb CHANGED
@@ -23,3 +23,10 @@ module Peeky
23
23
  class Error < StandardError; end
24
24
  # Your code goes here...
25
25
  end
26
+
27
+ if ENV['KLUE_DEBUG']&.to_s&.downcase == 'true'
28
+ namespace = 'Peeky::Version'
29
+ file_path = $LOADED_FEATURES.find { |f| f.include?('peeky/version') }
30
+ version = Peeky::VERSION.ljust(9)
31
+ puts "#{namespace.ljust(35)} : #{version.ljust(9)} : #{file_path}"
32
+ end
data/peeky.gemspec CHANGED
@@ -19,6 +19,10 @@ Gem::Specification.new do |spec|
19
19
  spec.metadata['homepage_uri'] = spec.homepage
20
20
  spec.metadata['source_code_uri'] = 'https://github.com/klueless-io/peeky'
21
21
  spec.metadata['changelog_uri'] = 'https://github.com/klueless-io/peeky/commits/master'
22
+ # Go to: https://rubydoc.info/
23
+ # Click Add Project:
24
+ # git@github.com:klueless-io/peeky
25
+ spec.metadata['documentation_uri'] = 'https://rubydoc.info/github/klueless-io/peeky/master'
22
26
 
23
27
  # Specify which files should be added to the gem when it is released.
24
28
  # The `git ls-files -z` loads the RubyGem files that have been added into git.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: peeky
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.39
4
+ version: 0.0.45
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Cruwys
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-02-03 00:00:00.000000000 Z
11
+ date: 2021-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -59,7 +59,6 @@ files:
59
59
  - lib/peeky/api.rb
60
60
  - lib/peeky/attr_info.rb
61
61
  - lib/peeky/class_info.rb
62
- - lib/peeky/example/yard_sample.rb
63
62
  - lib/peeky/method_info.rb
64
63
  - lib/peeky/parameter_info.rb
65
64
  - lib/peeky/predicates/attr_reader_predicate.rb
@@ -79,6 +78,7 @@ metadata:
79
78
  homepage_uri: http://appydave.com/gems/peeky
80
79
  source_code_uri: https://github.com/klueless-io/peeky
81
80
  changelog_uri: https://github.com/klueless-io/peeky/commits/master
81
+ documentation_uri: https://rubydoc.info/github/klueless-io/peeky/master
82
82
  post_install_message:
83
83
  rdoc_options:
84
84
  - "--title"
@@ -1,140 +0,0 @@
1
- module Peeky
2
- module Example
3
- # Yard sample
4
- class YardSample
5
- # A read write1
6
- attr_accessor :a_read_write1
7
-
8
- # A read write2
9
- attr_accessor :a_read_write2
10
-
11
- # A read write3
12
- attr_accessor :a_read_write3
13
-
14
- # B reader1
15
- attr_reader :b_reader1
16
-
17
- # B reader2
18
- attr_reader :b_reader2
19
-
20
- # E looks like an attr reader
21
- attr_reader :e_looks_like_an_attr_reader
22
-
23
- # C writer1
24
- attr_writer :c_writer1
25
-
26
- # C writer2
27
- attr_writer :c_writer2
28
-
29
- # Alpha sort1
30
- def alpha_sort1
31
- end
32
-
33
- # Alpha sort2
34
- def alpha_sort2
35
- end
36
-
37
- # D do something method
38
- def d_do_something_method
39
- end
40
-
41
- # E method with required param
42
- #
43
- # @param first_name [String] first name (required)
44
- def e_method_with_required_param(first_name)
45
- end
46
-
47
- # F method with required param and optional param
48
- #
49
- # @param first_name [String] first name (required)
50
- # @param last_name [String] last_name is optional, defaults to ''
51
- def f_method_with_required_param_and_optional_param(first_name, last_name = '')
52
- end
53
-
54
- # G method with required param and two optional params
55
- #
56
- # @param first_name [String] first name (required)
57
- # @param last_name [String] last_name is optional, defaults to ''
58
- # @param age [Integer] age is optional, defaults to 21
59
- def g_method_with_required_param_and_two_optional_params(first_name, last_name = '', age = 21)
60
- end
61
-
62
- # H list of optional parameters
63
- #
64
- # @param command_args [Array<Object>] *command_args - list of command args
65
- def h_list_of_optional_parameters(*command_args)
66
- end
67
-
68
- # I method with two required params and list of optional params
69
- #
70
- # @param first_name [String] first name (required)
71
- # @param last_name [String] last name (required)
72
- # @param alias_names [Array<Object>] *alias_names - list of alias names
73
- def i_method_with_two_required_params_and_list_of_optional_params(first_name, last_name, *alias_names)
74
- end
75
-
76
- # J method with list of named arguments
77
- #
78
- # @param options [<key: value>...] **options - list of key/values
79
- def j_method_with_list_of_named_arguments(**options)
80
- end
81
-
82
- # K method with block
83
- #
84
- # @param code_block [Block] &code_block
85
- def k_method_with_block(&code_block)
86
- end
87
-
88
- # L method with key value param required
89
- #
90
- # @param name [String] name: <value for name> (required)
91
- def l_method_with_key_value_param_required(name:)
92
- end
93
-
94
- # N method with key value param required and optional key value
95
- #
96
- # @param last_name [String] last_name: <value for last name> (required)
97
- # @param salutation [String] salutation: is optional, defaults to 'Mr'
98
- def n_method_with_key_value_param_required_and_optional_key_value(last_name:, salutation: 'Mr')
99
- end
100
-
101
- # P available?
102
-
103
- # @return [Boolean] true when p available?
104
- def p_available?
105
- end
106
-
107
- # Q danger will robinson!
108
- def q_danger_will_robinson!
109
- end
110
-
111
- # Z complex
112
- #
113
- # @param aaa [String] aaa (required)
114
- # @param bbb [Integer] bbb is optional, defaults to 1
115
- # @param ccc [Array<Object>] *ccc - list of ccc
116
- # @param ddd [String] ddd: <value for ddd> (required)
117
- # @param eee [Integer] eee: is optional, defaults to 1
118
- # @param fff [<key: value>...] **fff - list of key/values
119
- # @param ggg [Block] &ggg
120
- def z_complex(aaa, bbb = 1, *ccc, ddd:, eee: 1, **fff, &ggg)
121
- end
122
-
123
- # Z optional styles
124
- #
125
- # @param aaa [String] aaa (required)
126
- # @param bbb [Integer] bbb is optional, defaults to 123
127
- # @param ccc [String] ccc is optional, defaults to 'abc'
128
- # @param ddd [TrueClass] ddd is optional, defaults to true
129
- # @param eee [FalseClass] eee is optional, defaults to false
130
- # @param fff [Object] fff is optional, defaults to nil
131
- # @param ggg [Integer] ggg: is optional, defaults to 123
132
- # @param hhh [String] hhh: is optional, defaults to 'xyz'
133
- # @param iii [TrueClass] iii: is optional, defaults to true
134
- # @param jjj [FalseClass] jjj: is optional, defaults to false
135
- # @param kkk [Object] kkk: is optional, defaults to nil
136
- def z_optional_styles(aaa, bbb = 123, ccc = 'abc', ddd = true, eee = false, fff = nil, ggg: 123, hhh: 'xyz', iii: true, jjj: false, kkk: )
137
- end
138
- end
139
- end
140
- end