peeky 0.0.39 → 0.0.45

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.
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