peeky 0.0.33 → 0.0.43
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 +4 -4
- data/.github/workflows/ruby.yml +2 -3
- data/.rubocop.yml +6 -3
- data/Gemfile +15 -9
- data/Guardfile +4 -4
- data/README.md +4 -0
- data/Rakefile +15 -0
- data/USAGE2.md +5 -0
- data/lib/peeky/api.rb +13 -0
- data/lib/peeky/attr_info.rb +4 -0
- data/lib/peeky/class_info.rb +88 -40
- data/lib/peeky/method_info.rb +112 -31
- data/lib/peeky/parameter_info.rb +30 -29
- data/lib/peeky/predicates/attr_reader_predicate.rb +6 -1
- data/lib/peeky/renderer/class_debug_render.rb +19 -11
- data/lib/peeky/renderer/class_interface_render.rb +10 -4
- data/lib/peeky/renderer/class_interface_yard_render.rb +49 -38
- data/lib/peeky/renderer/method_call_minimum_params_render.rb +7 -3
- data/lib/peeky/version.rb +1 -1
- data/lib/peeky.rb +7 -0
- data/peeky.gemspec +5 -17
- metadata +7 -9
- data/lib/peeky/example/yard_sample.rb +0 -124
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a5ace1c867116904f98e261077b746cd8d2621f657a391e79c80f3f57edf4583
|
4
|
+
data.tar.gz: 195ab81abb7ab1198c19613c4fe2f4e730fd2b6a6c2654938396ad191dde8e25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db4dd2ec06b1722637d716611c9d6ae6080f1b52ffa2da6129e8a421e0a034ea5923f56ea041869d69e7bd0fe48656a759f01c29d8067ec64cbd5e7ee7956c24
|
7
|
+
data.tar.gz: 56982a728fc581b06080ede29139b2245770affe03d9ce97633d18ac7d56341536740d4b15b52e1264ff26bc4b7e27ad4f7548489b0d0879f1c9569c34c1dd90
|
data/.github/workflows/ruby.yml
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
2
2
|
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
3
|
-
|
4
3
|
name: Ruby
|
5
4
|
|
6
5
|
on:
|
@@ -19,10 +18,10 @@ jobs:
|
|
19
18
|
- name: Set up Ruby
|
20
19
|
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
21
20
|
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
22
|
-
|
23
|
-
uses: ruby/setup-ruby@ec106b438a1ff6ff109590de34ddc62c540232e0
|
21
|
+
uses: ruby/setup-ruby@v1
|
24
22
|
with:
|
25
23
|
ruby-version: 2.6
|
24
|
+
# bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
26
25
|
- name: Install dependencies
|
27
26
|
run: bundle install
|
28
27
|
- name: Run tests
|
data/.rubocop.yml
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
AllCops:
|
2
|
+
TargetRubyVersion: 2.5
|
2
3
|
DisplayCopNames: true
|
3
4
|
ExtraDetails: true
|
4
5
|
NewCops: enable
|
5
6
|
Exclude:
|
6
7
|
- "_/**/*"
|
7
|
-
- "
|
8
|
+
- "spec/sample/**/*"
|
8
9
|
|
9
10
|
# My Preferences - Start
|
11
|
+
Metrics/ClassLength:
|
12
|
+
Enabled: false
|
10
13
|
Naming/MemoizedInstanceVariableName:
|
11
14
|
Enabled: false
|
12
15
|
Naming/VariableNumber:
|
@@ -35,9 +38,9 @@ Layout/SpaceBeforeComma:
|
|
35
38
|
|
36
39
|
Metrics/BlockLength:
|
37
40
|
Exclude:
|
38
|
-
- "**/spec
|
41
|
+
- "**/spec/**/*"
|
39
42
|
- "*.gemspec"
|
40
|
-
|
43
|
+
IgnoredMethods:
|
41
44
|
- configure
|
42
45
|
- context
|
43
46
|
- define
|
data/Gemfile
CHANGED
@@ -5,19 +5,25 @@ source 'https://rubygems.org'
|
|
5
5
|
# Specify your gem's dependencies in poc_github_ap.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
|
8
|
+
group :development do
|
9
|
+
# pry on steroids
|
10
|
+
# gem 'pry-coolline', github: 'owst/pry-coolline', branch: 'support_new_pry_config_api'
|
11
|
+
# gem 'jazz_fingers'
|
12
|
+
end
|
13
13
|
|
14
14
|
group :development, :test do
|
15
|
-
gem 'guard-bundler'
|
16
|
-
gem 'guard-rspec'
|
17
|
-
gem 'guard-rubocop'
|
15
|
+
gem 'guard-bundler', '~> 3.0'
|
16
|
+
gem 'guard-rspec', '~> 4.0'
|
17
|
+
gem 'guard-rubocop', '~> 1.2'
|
18
18
|
gem 'rake', '~> 12.0'
|
19
19
|
# this is used for cmdlets 'self-executing gems'
|
20
20
|
gem 'rake-compiler'
|
21
21
|
gem 'rspec', '~> 3.0'
|
22
|
-
gem 'rubocop'
|
22
|
+
gem 'rubocop', '~> 1.9'
|
23
|
+
gem 'rubocop-rake', require: false
|
24
|
+
gem 'rubocop-rspec', require: false
|
23
25
|
end
|
26
|
+
|
27
|
+
# group :test do
|
28
|
+
# gem 'k_usecases', path: '~/dev/kgems/k_usecases'
|
29
|
+
# end
|
data/Guardfile
CHANGED
@@ -23,8 +23,8 @@ 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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
guard :rubocop, all_on_start: false, cli: ['--format', 'clang'] do
|
27
|
+
watch(%r{.+\.rb$})
|
28
|
+
watch(%r{(?:.+/)?\.rubocop(?:_todo)?\.yml$}) { |m| File.dirname(m[0]) }
|
29
|
+
end
|
30
30
|
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]
|
data/USAGE2.md
ADDED
data/lib/peeky/api.rb
CHANGED
@@ -16,6 +16,9 @@ module Peeky
|
|
16
16
|
# ClassInfo stores information about the instance of a
|
17
17
|
# class that is passed in including methods, attr_accessors
|
18
18
|
# attr_readers and attr_writers.
|
19
|
+
#
|
20
|
+
# @param instance [Object] instance of class to gather information about (required)
|
21
|
+
# @param lazy [TrueClass] lazy load method and parameter information, laze: is optional, defaults to true
|
19
22
|
def build_class_info(instance, lazy: true)
|
20
23
|
ci = Peeky::ClassInfo.new(instance)
|
21
24
|
ci.load unless lazy
|
@@ -23,6 +26,14 @@ module Peeky
|
|
23
26
|
end
|
24
27
|
|
25
28
|
# Render a class using a predefined class renderer
|
29
|
+
#
|
30
|
+
# ^1: One of class_info and instance must supplied, they are mutually
|
31
|
+
# exclusive to each other.
|
32
|
+
#
|
33
|
+
# @param render_key [Symbol] class render key (required)
|
34
|
+
# @param class_info [Object] class_info: is optional^1, defaults to nil
|
35
|
+
# @param instance [Object] instance: is optional^1, defaults to nil
|
36
|
+
# @param _opts [<key: value>...] **_opts - list of key/values that can help configure render
|
26
37
|
def render_class(render_key, class_info: nil, instance: nil, **_opts)
|
27
38
|
raise 'Call render_class with class_info OR instance.' if class_info.nil? && instance.nil?
|
28
39
|
raise 'Call render_class with class_info OR instance, these parameters are mutually exclusive' if !class_info.nil? && !instance.nil?
|
@@ -37,6 +48,7 @@ module Peeky
|
|
37
48
|
# Get a method renderer by :key
|
38
49
|
#
|
39
50
|
# TODO: Refactor to a configurable system
|
51
|
+
# @param key [String] key is a shortcut to a specific Peeky::Render that handles method_info (required)
|
40
52
|
def method_renderer(key)
|
41
53
|
case key
|
42
54
|
when :signature
|
@@ -53,6 +65,7 @@ module Peeky
|
|
53
65
|
# Get a class renderer by :key
|
54
66
|
#
|
55
67
|
# TODO: Refactor to a configurable system
|
68
|
+
# @param key [String] key is a shortcut to a specific Peeky::Renderer that handles class_info (required)
|
56
69
|
def class_renderer(key)
|
57
70
|
case key
|
58
71
|
when :class_debug
|
data/lib/peeky/attr_info.rb
CHANGED
@@ -6,7 +6,9 @@ module Peeky
|
|
6
6
|
# Attr Info is a container that holds read, write or read/write
|
7
7
|
# attributes in the form of MethodInfo objects
|
8
8
|
class AttrInfo
|
9
|
+
# reader stores a MethodInfo for a matching reader, nil if readable style method_info not found
|
9
10
|
attr_reader :reader
|
11
|
+
# writer stores a MethodInfo for a matching writer, nil if writable style method_info not found
|
10
12
|
attr_reader :writer
|
11
13
|
|
12
14
|
def initialize(reader: nil, writer: nil)
|
@@ -16,6 +18,7 @@ module Peeky
|
|
16
18
|
@writer = writer
|
17
19
|
end
|
18
20
|
|
21
|
+
# Type of the attribute [:attr_writer, :attr_reader or :attr_accessor]
|
19
22
|
def type
|
20
23
|
@type ||= if @reader.nil?
|
21
24
|
:attr_writer
|
@@ -24,6 +27,7 @@ module Peeky
|
|
24
27
|
end
|
25
28
|
end
|
26
29
|
|
30
|
+
# Name of the attribute
|
27
31
|
def name
|
28
32
|
@name ||= @reader.nil? ? @writer.clean_name : @reader.clean_name
|
29
33
|
end
|
data/lib/peeky/class_info.rb
CHANGED
@@ -17,9 +17,33 @@ module Peeky
|
|
17
17
|
@instance = instance
|
18
18
|
end
|
19
19
|
|
20
|
+
# rubocop:disable Metrics/AbcSize
|
20
21
|
def to_s
|
21
|
-
|
22
|
+
result = []
|
23
|
+
result.push kv('class', class_full_name)
|
24
|
+
if defined?(@_ruby_instance_method_names)
|
25
|
+
result.push kv('# of instance methods', @_ruby_instance_method_names.join(', '))
|
26
|
+
else
|
27
|
+
result.push kv('# of instance methods', '')
|
28
|
+
end
|
29
|
+
if defined?(@signatures)
|
30
|
+
result.push kv('# of accessors', accessors.length)
|
31
|
+
result.push kv('# of readers', readers.length)
|
32
|
+
result.push kv('# of writers', writers.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
|
+
else
|
37
|
+
result.push kv('# of accessors', '')
|
38
|
+
result.push kv('# of readers', '')
|
39
|
+
result.push kv('# of writers', '')
|
40
|
+
result.push kv('# of methods', '')
|
41
|
+
result.push kv('# of methods - public', '')
|
42
|
+
result.push kv('# of methods - private', '')
|
43
|
+
end
|
44
|
+
result.join("\n")
|
22
45
|
end
|
46
|
+
# rubocop:enable Metrics/AbcSize
|
23
47
|
|
24
48
|
# Load class_info
|
25
49
|
#
|
@@ -29,8 +53,6 @@ module Peeky
|
|
29
53
|
# At times during debug or other edge cases, it may be useful to
|
30
54
|
# pre-load this information early.
|
31
55
|
def load
|
32
|
-
ruby_instance_methods
|
33
|
-
ruby_instance_method_names
|
34
56
|
signatures
|
35
57
|
end
|
36
58
|
|
@@ -41,19 +63,19 @@ module Peeky
|
|
41
63
|
|
42
64
|
# Class name
|
43
65
|
def class_name
|
44
|
-
@
|
66
|
+
@class_name ||= class_full_name.to_s.gsub(/^.*::/, '')
|
45
67
|
# instance.class.name.split('::').last
|
46
68
|
end
|
47
69
|
|
48
70
|
# Module name
|
49
71
|
def module_name
|
50
|
-
@
|
72
|
+
@module_name ||= class_full_name.to_s.gsub(/(.*)::.*/, '\1')
|
51
73
|
end
|
52
74
|
|
53
75
|
# Get a list of :attr_accessor on the class
|
54
76
|
# @return [Array<AttrInfo>] list of AttrInfo where type is :attr_accessor
|
55
77
|
def accessors
|
56
|
-
@
|
78
|
+
@accessors ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_accessor }
|
57
79
|
end
|
58
80
|
|
59
81
|
# Get a list of :attr_accessors ordered the way they are in the source code
|
@@ -66,7 +88,7 @@ module Peeky
|
|
66
88
|
|
67
89
|
# Attribute infos
|
68
90
|
def attribute_infos
|
69
|
-
@
|
91
|
+
@attribute_infos ||= begin
|
70
92
|
grouped_method_infos = signatures.select { |signature| signature.readable? || signature.writable? }.group_by(&:clean_name)
|
71
93
|
|
72
94
|
grouped_method_infos.keys.map { |key| AttrInfo.create(*grouped_method_infos[key]) }
|
@@ -82,8 +104,26 @@ module Peeky
|
|
82
104
|
|
83
105
|
# Get a list methods
|
84
106
|
# @return [Array<MethodInfo>] list of MethodInfo where type is :method
|
85
|
-
def
|
86
|
-
@
|
107
|
+
def all_methods
|
108
|
+
@all_methods ||= signatures.select { |signature| signature.implementation_type == :method }
|
109
|
+
end
|
110
|
+
|
111
|
+
# Get a list of private methods
|
112
|
+
# @return [Array<MethodInfo>] list of MethodInfo where type is :method
|
113
|
+
def private_methods
|
114
|
+
@private_methods ||= signatures.select { |signature| signature.implementation_type == :method && signature.access_control == :private }
|
115
|
+
end
|
116
|
+
|
117
|
+
# Get a list of public methods
|
118
|
+
# @return [Array<MethodInfo>] list of MethodInfo where type is :method
|
119
|
+
def public_methods
|
120
|
+
@public_methods ||= signatures.select { |signature| signature.implementation_type == :method && signature.access_control == :public }
|
121
|
+
end
|
122
|
+
|
123
|
+
# Get a list of class methods
|
124
|
+
# @return [Array<MethodInfo>] list of MethodInfo where type is :method
|
125
|
+
def class_methods
|
126
|
+
@class_methods ||= signatures.select { |signature| signature.implementation_type == :class_method }
|
87
127
|
end
|
88
128
|
|
89
129
|
# Get a list methods ordered the way they are in the source code
|
@@ -91,7 +131,7 @@ module Peeky
|
|
91
131
|
def methods_source_order
|
92
132
|
# TODO: This feature is required
|
93
133
|
# May be best to have a sort object that can be created for each type of ordering that is needed
|
94
|
-
|
134
|
+
all_methods
|
95
135
|
end
|
96
136
|
|
97
137
|
# Reader by name
|
@@ -104,7 +144,7 @@ module Peeky
|
|
104
144
|
# Get a list of :attr_reader on the class
|
105
145
|
# @return [Array<AttrInfo>] list of AttrInfo where type is :attr_accessor
|
106
146
|
def readers
|
107
|
-
@
|
147
|
+
@readers ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_reader }
|
108
148
|
end
|
109
149
|
|
110
150
|
# Get a list of :attr_reader ordered the way they are in the source code
|
@@ -118,7 +158,7 @@ module Peeky
|
|
118
158
|
# Get a list of :attr_writer on the class
|
119
159
|
# @return [Array<AttrInfo>] list of AttrInfo where type is :attr_writer
|
120
160
|
def writers
|
121
|
-
@
|
161
|
+
@writers ||= attribute_infos.select { |attribute_info| attribute_info.type == :attr_writer }
|
122
162
|
end
|
123
163
|
|
124
164
|
# Get a list of :attr_writer ordered the way they are in the source code
|
@@ -141,7 +181,14 @@ module Peeky
|
|
141
181
|
# such as static, private vs public
|
142
182
|
# deep, deep_to_level, this_instance.
|
143
183
|
def signatures
|
144
|
-
@
|
184
|
+
return @signatures if defined? @signatures
|
185
|
+
|
186
|
+
@signatures = begin
|
187
|
+
instance_methods = ruby_instance_methods.map { |im| MethodInfo.new(im, @instance) }
|
188
|
+
private_methods = ruby_private_methods.map { |im| MethodInfo.new(im, @instance, access_control: :private) }
|
189
|
+
class_methods = ruby_class_methods.map { |im| MethodInfo.new(im, @instance, implementation_type: :class_method) }
|
190
|
+
instance_methods + private_methods + class_methods
|
191
|
+
end
|
145
192
|
end
|
146
193
|
|
147
194
|
# Signatures by clean name
|
@@ -161,41 +208,42 @@ module Peeky
|
|
161
208
|
signatures.select { |im| im.name == name && im.implementation_type == filter_type }
|
162
209
|
end
|
163
210
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
# for production
|
169
|
-
# @param format [String] format: <value for format> (optional)
|
170
|
-
def debug(format: [:signatures])
|
171
|
-
debug_method_names if format.include?(:method_names)
|
172
|
-
|
173
|
-
return unless format.include?(:signatures)
|
174
|
-
|
175
|
-
puts '-' * 70
|
176
|
-
puts 'Methods'
|
177
|
-
puts '-' * 70
|
178
|
-
signatures.each(&:debug)
|
179
|
-
end
|
180
|
-
|
181
|
-
def debug_method_names
|
182
|
-
puts '-' * 70
|
183
|
-
puts 'Method Names'
|
184
|
-
puts '-' * 70
|
185
|
-
ruby_instance_method_names.each do |method_name|
|
186
|
-
puts method_name
|
187
|
-
end
|
211
|
+
private
|
212
|
+
|
213
|
+
def kv(key, value)
|
214
|
+
"#{key.to_s.ljust(25)}: #{value}"
|
188
215
|
end
|
189
216
|
|
190
|
-
|
217
|
+
def ruby_class_method_names
|
218
|
+
@ruby_class_method_names ||= instance.class.singleton_class.instance_methods(false).sort
|
219
|
+
end
|
191
220
|
|
192
221
|
def ruby_instance_method_names
|
193
|
-
@
|
222
|
+
@ruby_instance_method_names ||= instance.class.instance_methods(false).sort
|
223
|
+
end
|
224
|
+
|
225
|
+
def ruby_private_method_names
|
226
|
+
@ruby_private_method_names ||= instance.private_methods(false).sort
|
227
|
+
end
|
228
|
+
|
229
|
+
def ruby_class_methods
|
230
|
+
@ruby_class_methods ||= ruby_class_method_names.map { |method_name| instance.class.method(method_name) }
|
231
|
+
rescue StandardError => e
|
232
|
+
# puts 'ruby_class_methods'
|
233
|
+
puts e
|
234
|
+
end
|
235
|
+
|
236
|
+
def ruby_private_methods
|
237
|
+
@ruby_private_methods ||= ruby_private_method_names.map { |method_name| instance.method(method_name) }
|
238
|
+
rescue StandardError => e
|
239
|
+
# puts 'ruby_private_methods'
|
240
|
+
puts e
|
194
241
|
end
|
195
242
|
|
196
243
|
def ruby_instance_methods
|
197
|
-
@
|
244
|
+
@ruby_instance_methods ||= ruby_instance_method_names.map { |method_name| instance.method(method_name) }
|
198
245
|
rescue StandardError => e
|
246
|
+
# puts 'ruby_instance_methods'
|
199
247
|
puts e
|
200
248
|
end
|
201
249
|
end
|
data/lib/peeky/method_info.rb
CHANGED
@@ -14,28 +14,40 @@ 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
|
22
|
+
#
|
20
23
|
|
21
24
|
# Implementation type indicates the probable representation of this
|
22
|
-
# method in ruby, was it
|
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`
|
23
30
|
attr_reader :implementation_type
|
24
31
|
|
25
|
-
|
26
|
-
def initialize(method, target_instance = nil)
|
32
|
+
def initialize(method, target_instance, implementation_type: :method, access_control: :public)
|
27
33
|
@focal_method = method
|
34
|
+
@target_instance = target_instance
|
35
|
+
@access_control = access_control
|
36
|
+
@implementation_type = implementation_type
|
28
37
|
@parameters = ParameterInfo.from_method(method)
|
29
|
-
# stage 1
|
30
|
-
# @implementation_type = :method
|
31
38
|
|
32
|
-
|
33
|
-
|
39
|
+
infer_implementation_type
|
40
|
+
infer_default_paramaters
|
34
41
|
end
|
35
42
|
|
36
43
|
# Stage 2 (working out) attr_accessor
|
44
|
+
#
|
45
|
+
|
37
46
|
# Name of method minus writer annotations
|
38
|
-
# Example
|
47
|
+
# Example
|
48
|
+
# :writable_attribute=
|
49
|
+
# # becomes
|
50
|
+
# :writable_attribute
|
39
51
|
def clean_name
|
40
52
|
@clean_name ||= begin
|
41
53
|
n = name.to_s
|
@@ -43,43 +55,112 @@ module Peeky
|
|
43
55
|
end
|
44
56
|
end
|
45
57
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
58
|
+
# Infer implementation type [:class_method, :method, :attr_reader or :attr_writer]
|
59
|
+
def infer_implementation_type
|
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)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Get parameter by name
|
67
|
+
#
|
68
|
+
# @param name [String] name (required)
|
69
|
+
def get_parameter(name)
|
70
|
+
name = name.to_s
|
71
|
+
parameters.find { |p| p.name == name }
|
72
|
+
end
|
73
|
+
|
74
|
+
# Has any optional paramaters?
|
75
|
+
|
76
|
+
# @return [Boolean] true when any parameter is optional?
|
77
|
+
def optional?
|
78
|
+
parameters.any?(&:optional?)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Infer default paramater values
|
82
|
+
#
|
83
|
+
# WARNING: Unit test coverage went from .1 seconds to 30-40 seconds
|
84
|
+
# when I first introduced this method.
|
85
|
+
#
|
86
|
+
# I now only call TracePoint if I have optional parameters to be inferred.
|
87
|
+
#
|
88
|
+
# The tests are now down to 5 seconds, but it highlights the cost of use
|
89
|
+
# TracePoint.
|
90
|
+
def infer_default_paramaters
|
91
|
+
minimalist_method = Peeky::Renderer::MethodCallMinimumParamsRender.new(self).render
|
92
|
+
|
93
|
+
return if minimalist_method.end_with?('=')
|
94
|
+
return unless optional?
|
95
|
+
|
96
|
+
tracer.enable do
|
97
|
+
if @implementation_type == :method
|
98
|
+
@target_instance.instance_eval(minimalist_method)
|
99
|
+
end
|
100
|
+
if @implementation_type == :class_method
|
101
|
+
minimalist_method = "#{@target_instance.class.name}.#{minimalist_method}"
|
102
|
+
@target_instance.class.instance_eval(minimalist_method)
|
103
|
+
end
|
104
|
+
rescue StandardError => e
|
105
|
+
# just print the error for now, we are only attempting to capture the
|
106
|
+
# first call, any errors inside the call cannot be dealt with and should
|
107
|
+
# not be re-raised
|
108
|
+
puts e.message
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def tracer
|
113
|
+
TracePoint.trace(:call, :c_call) do |tp|
|
114
|
+
next unless tp.self.is_a?(@target_instance.class)
|
115
|
+
next unless tp.method_id == name
|
116
|
+
|
117
|
+
tp.parameters.each do |_type, param_name|
|
118
|
+
method_paramater = get_parameter(param_name)
|
119
|
+
|
120
|
+
if method_paramater.optional?
|
121
|
+
value = tp.binding.local_variable_get(param_name)
|
122
|
+
method_paramater.default_value = value
|
123
|
+
end
|
124
|
+
end
|
55
125
|
end
|
56
126
|
end
|
57
127
|
|
58
|
-
|
59
|
-
|
128
|
+
# Match
|
129
|
+
#
|
130
|
+
# @param predicate [String] use a predicate object with the signature match(instance, method_info)
|
131
|
+
def match(predicate)
|
132
|
+
predicate.new.match(@target_instance, self)
|
60
133
|
end
|
61
134
|
|
135
|
+
# Method?
|
136
|
+
|
137
|
+
# @return [Boolean] true when implementation type is method?
|
62
138
|
def method?
|
63
139
|
@implementation_type == :method
|
64
140
|
end
|
65
141
|
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
# Cannot read property 'namedChildren' of undefined
|
142
|
+
# Readable?
|
143
|
+
#
|
144
|
+
# @return [Boolean] true when readable?
|
70
145
|
def readable?
|
146
|
+
# Method naming issue: VSCode Ruby Language Server
|
147
|
+
#
|
148
|
+
# If this method is renamed to attr_readable, same for attr_writable.
|
149
|
+
#
|
150
|
+
# https://github.com/rubyide/vscode-ruby/issues/454
|
151
|
+
# if I prefix these methods with attr_ then will get an issue
|
152
|
+
# in the language server.
|
153
|
+
#
|
154
|
+
# Cannot read property 'namedChildren' of undefined
|
155
|
+
|
71
156
|
@implementation_type == :attr_reader
|
72
157
|
end
|
73
158
|
|
159
|
+
# Writable?
|
160
|
+
|
161
|
+
# @return [Boolean] true when implementation_type writable?
|
74
162
|
def writable?
|
75
163
|
@implementation_type == :attr_writer
|
76
164
|
end
|
77
|
-
|
78
|
-
def debug
|
79
|
-
puts '-' * 70
|
80
|
-
puts name
|
81
|
-
puts '-' * 70
|
82
|
-
parameters.each(&:debug)
|
83
|
-
end
|
84
165
|
end
|
85
166
|
end
|
data/lib/peeky/parameter_info.rb
CHANGED
@@ -48,13 +48,6 @@ module Peeky
|
|
48
48
|
ruby_method.parameters.map { |ruby_paramater| from_parameter(ruby_paramater) }
|
49
49
|
end
|
50
50
|
|
51
|
-
def debug
|
52
|
-
puts "name : #{name}"
|
53
|
-
puts "type : #{type}"
|
54
|
-
puts "signature_format : #{signature_format}"
|
55
|
-
puts "minimal_call_format : #{minimal_call_format}"
|
56
|
-
end
|
57
|
-
|
58
51
|
# ruby code formatted for use in a method signature
|
59
52
|
def signature_format
|
60
53
|
@_signature_format ||= begin
|
@@ -79,6 +72,34 @@ module Peeky
|
|
79
72
|
end
|
80
73
|
end
|
81
74
|
|
75
|
+
# Optional?
|
76
|
+
|
77
|
+
# @return [Boolean] true when parameter is one of the optional types?
|
78
|
+
def optional?
|
79
|
+
@_optional |= (@type == :param_optional || @type == :key_optional)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Default value type will look at the default value and try to
|
83
|
+
# infer the class behind it. Will default to 'Object' fi nil
|
84
|
+
def default_value_type
|
85
|
+
if @default_value.nil?
|
86
|
+
'Object'
|
87
|
+
else
|
88
|
+
@default_value.class
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Wrap default value in quotes if string, or no wrapping otherwise
|
93
|
+
#
|
94
|
+
# @param value_for_nil [String] value for nil, generally '' or 'nil' (required)
|
95
|
+
def wrap_default_value(value_for_nil)
|
96
|
+
if @default_value.is_a?(String)
|
97
|
+
"'#{@default_value}'"
|
98
|
+
else
|
99
|
+
@default_value.nil? ? value_for_nil : @default_value
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
82
103
|
private
|
83
104
|
|
84
105
|
# Convert the limited information provided by ruby method.parameters
|
@@ -118,7 +139,7 @@ module Peeky
|
|
118
139
|
end
|
119
140
|
|
120
141
|
def signature_format_param_optional
|
121
|
-
"#{name} = nil" # signature format needs to be moved to a method
|
142
|
+
"#{name} = #{wrap_default_value('nil')}" # signature format needs to be moved to a method
|
122
143
|
end
|
123
144
|
|
124
145
|
def signature_format_splat
|
@@ -130,7 +151,7 @@ module Peeky
|
|
130
151
|
end
|
131
152
|
|
132
153
|
def signature_format_key_optional
|
133
|
-
"#{name}:
|
154
|
+
"#{name}: #{wrap_default_value('')}"
|
134
155
|
end
|
135
156
|
|
136
157
|
def signature_format_double_splat
|
@@ -152,28 +173,8 @@ module Peeky
|
|
152
173
|
"'#{@name}'"
|
153
174
|
end
|
154
175
|
|
155
|
-
# def minimal_call_format_param_optional
|
156
|
-
# ''
|
157
|
-
# end
|
158
|
-
|
159
|
-
# def minimal_call_format_splat
|
160
|
-
# ''
|
161
|
-
# end
|
162
|
-
|
163
176
|
def minimal_call_format_key_required
|
164
177
|
"#{@name}: '#{@name}'"
|
165
178
|
end
|
166
|
-
|
167
|
-
# def minimal_call_format_key_optional
|
168
|
-
# ''
|
169
|
-
# end
|
170
|
-
|
171
|
-
# def minimal_call_format_double_splat
|
172
|
-
# ''
|
173
|
-
# end
|
174
|
-
|
175
|
-
# def minimal_call_format_block
|
176
|
-
# ''
|
177
|
-
# end
|
178
179
|
end
|
179
180
|
end
|
@@ -32,7 +32,12 @@ module Peeky
|
|
32
32
|
cloned = instance.clone
|
33
33
|
|
34
34
|
cloned.instance_eval(code)
|
35
|
-
|
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
|
|
@@ -19,15 +19,23 @@ module Peeky
|
|
19
19
|
attributes = render_accessors + render_readers + render_writers
|
20
20
|
|
21
21
|
if attributes.length.positive?
|
22
|
-
output.push("-- Attributes #{'-' *
|
22
|
+
output.push("-- Attributes #{'-' * 86}")
|
23
23
|
output.push(*attributes)
|
24
24
|
output.push('')
|
25
25
|
end
|
26
26
|
|
27
|
-
methods = render_methods
|
27
|
+
methods = render_methods(@class_info.public_methods)
|
28
28
|
|
29
29
|
if methods.length.positive?
|
30
|
-
output.push("-- Public Methods #{'-' *
|
30
|
+
output.push("-- Public Methods #{'-' * 82}")
|
31
|
+
output.push(*methods)
|
32
|
+
output.push('')
|
33
|
+
end
|
34
|
+
|
35
|
+
methods = render_methods(@class_info.private_methods)
|
36
|
+
|
37
|
+
if methods.length.positive?
|
38
|
+
output.push("-- Private Methods #{'-' * 82}")
|
31
39
|
output.push(*methods)
|
32
40
|
output.push('')
|
33
41
|
end
|
@@ -40,7 +48,7 @@ module Peeky
|
|
40
48
|
|
41
49
|
private
|
42
50
|
|
43
|
-
def lj(value, size =
|
51
|
+
def lj(value, size = 24)
|
44
52
|
value.to_s.ljust(size)
|
45
53
|
end
|
46
54
|
|
@@ -50,7 +58,7 @@ module Peeky
|
|
50
58
|
|
51
59
|
def class_details
|
52
60
|
[
|
53
|
-
'-' *
|
61
|
+
'-' * 100,
|
54
62
|
kv('class name', @class_info.class_name),
|
55
63
|
kv('module name', @class_info.module_name),
|
56
64
|
kv('class full name', @class_info.class_full_name),
|
@@ -70,10 +78,10 @@ module Peeky
|
|
70
78
|
@class_info.writers.map { |attr| kv('attr_writer', attr.name) }
|
71
79
|
end
|
72
80
|
|
73
|
-
def render_methods
|
74
|
-
|
81
|
+
def render_methods(method_list)
|
82
|
+
method_list.flat_map do |method|
|
75
83
|
[
|
76
|
-
"#{method.name}
|
84
|
+
"[ #{method.name} ]",
|
77
85
|
*render_paramaters(method.parameters),
|
78
86
|
''
|
79
87
|
]
|
@@ -82,12 +90,12 @@ module Peeky
|
|
82
90
|
|
83
91
|
def render_paramaters(parameters)
|
84
92
|
result = [
|
85
|
-
"#{lj('name')} #{lj('param format')} #{lj('type')}",
|
86
|
-
'-' *
|
93
|
+
"#{lj('name')} #{lj('param format')} #{lj('type')} #{lj('default')}",
|
94
|
+
'-' * 100
|
87
95
|
]
|
88
96
|
|
89
97
|
result + parameters.map do |param|
|
90
|
-
"#{lj(param.name)} #{lj(param.signature_format)} #{lj(param.type)}"
|
98
|
+
"#{lj(param.name)} #{lj(param.signature_format)} #{lj(param.type)} #{lj(param.default_value)}"
|
91
99
|
end
|
92
100
|
end
|
93
101
|
end
|
@@ -38,15 +38,20 @@ module Peeky
|
|
38
38
|
end
|
39
39
|
|
40
40
|
# Render the class interface
|
41
|
+
# rubocop:disable Metrics/AbcSize
|
41
42
|
def render
|
42
43
|
@indent = ''
|
43
|
-
output
|
44
|
+
output = []
|
44
45
|
output.push render_start
|
45
46
|
@indent = ' '
|
46
47
|
output += render_accessors
|
47
48
|
output += render_readers
|
48
49
|
output += render_writers
|
49
|
-
output += render_methods
|
50
|
+
output += render_methods(@class_info.public_methods)
|
51
|
+
unless @class_info.private_methods.length.zero?
|
52
|
+
output += ["#{@indent}private", '']
|
53
|
+
output += render_methods(@class_info.private_methods)
|
54
|
+
end
|
50
55
|
output.pop if output.last == ''
|
51
56
|
|
52
57
|
@indent = ''
|
@@ -54,6 +59,7 @@ module Peeky
|
|
54
59
|
|
55
60
|
output.join("\n")
|
56
61
|
end
|
62
|
+
# rubocop:enable Metrics/AbcSize
|
57
63
|
|
58
64
|
private
|
59
65
|
|
@@ -79,8 +85,8 @@ module Peeky
|
|
79
85
|
result
|
80
86
|
end
|
81
87
|
|
82
|
-
def render_methods
|
83
|
-
result =
|
88
|
+
def render_methods(method_list)
|
89
|
+
result = method_list.map do |method_signature|
|
84
90
|
render_signature = Peeky::Renderer::MethodSignatureRender.new(method_signature)
|
85
91
|
"#{@indent}#{render_signature.render}"
|
86
92
|
end
|
@@ -88,50 +88,61 @@ module Peeky
|
|
88
88
|
result
|
89
89
|
end
|
90
90
|
|
91
|
-
# rubocop:disable
|
91
|
+
# rubocop:disable Metics/AbcSize
|
92
92
|
def render_methods
|
93
93
|
result = []
|
94
|
-
class_info.
|
95
|
-
result
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
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} [#{default_param_type}] #{parameter.name}: <value for #{parameter.name.to_s.humanize.downcase}> (optional)"
|
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} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase} (optional)"
|
116
|
-
else
|
117
|
-
result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase}"
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
if method_signature.name.to_s.end_with?('?')
|
122
|
-
result.push ''
|
123
|
-
result.push "#{@indent}# @return [Boolean] true when #{method_signature.name.to_s.humanize.downcase}"
|
124
|
-
end
|
125
|
-
|
126
|
-
render_signature = Peeky::Renderer::MethodSignatureRender.new(method_signature)
|
127
|
-
render_signature.indent = @indent
|
128
|
-
render_signature.style = :default
|
129
|
-
result.push render_signature.render
|
94
|
+
class_info.public_methods.map.with_index do |method_signature, index|
|
95
|
+
render_method(result, method_signature, index)
|
96
|
+
end
|
97
|
+
class_info.private_methods.map.with_index do |method_signature, index|
|
98
|
+
result.push "\n#{indent}private\n" if index.zero?
|
99
|
+
render_method(result, method_signature, index)
|
130
100
|
end
|
131
101
|
result.push '' unless result.length.zero?
|
132
102
|
result
|
133
103
|
end
|
134
|
-
# rubocop:enable
|
104
|
+
# rubocop:enable Metics/AbcSize
|
105
|
+
|
106
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
107
|
+
def render_method(result, method_signature, index)
|
108
|
+
result.push '' if index.positive?
|
109
|
+
result.push "#{@indent}# #{method_signature.name.to_s.humanize}"
|
110
|
+
|
111
|
+
method_signature.parameters.each_with_index do |parameter, param_index|
|
112
|
+
result.push "#{@indent}#" if param_index.zero?
|
113
|
+
|
114
|
+
case parameter.type
|
115
|
+
when :splat
|
116
|
+
result.push "#{@indent}# @param #{parameter.name} [Array<#{default_splat_param_type}>] *#{parameter.name} - list of #{parameter.name.to_s.humanize.downcase}"
|
117
|
+
when :double_splat
|
118
|
+
result.push "#{@indent}# @param #{parameter.name} [<key: value>...] **#{parameter.name} - list of key/values"
|
119
|
+
when :block
|
120
|
+
result.push "#{@indent}# @param #{parameter.name} [Block] &#{parameter.name}"
|
121
|
+
when :key_required
|
122
|
+
result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name}: <value for #{parameter.name.to_s.humanize.downcase}> (required)"
|
123
|
+
when :key_optional
|
124
|
+
result.push "#{@indent}# @param #{parameter.name} [#{parameter.default_value_type}] #{parameter.name}: is optional, defaults to #{parameter.wrap_default_value('nil')}"
|
125
|
+
when :param_required
|
126
|
+
result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase} (required)"
|
127
|
+
when :param_optional
|
128
|
+
result.push "#{@indent}# @param #{parameter.name} [#{parameter.default_value_type}] #{parameter.name} is optional, defaults to #{parameter.wrap_default_value('nil')}"
|
129
|
+
# result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase} (optional)"
|
130
|
+
else
|
131
|
+
result.push "#{@indent}# @param #{parameter.name} [#{default_param_type}] #{parameter.name.to_s.humanize.downcase}"
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
if method_signature.name.to_s.end_with?('?')
|
136
|
+
result.push ''
|
137
|
+
result.push "#{@indent}# @return [Boolean] true when #{method_signature.name.to_s.humanize.downcase}"
|
138
|
+
end
|
139
|
+
|
140
|
+
render_signature = Peeky::Renderer::MethodSignatureRender.new(method_signature)
|
141
|
+
render_signature.indent = @indent
|
142
|
+
render_signature.style = :default
|
143
|
+
result.push render_signature.render
|
144
|
+
end
|
145
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
135
146
|
|
136
147
|
def render_end
|
137
148
|
"#{@indent}end"
|
@@ -12,8 +12,8 @@ module Peeky
|
|
12
12
|
attr_reader :method_signature
|
13
13
|
|
14
14
|
def initialize(method_signature, **opts)
|
15
|
-
instance_name = opts[:instance_name] || 'instance'
|
16
|
-
@instance_name = instance_name
|
15
|
+
# instance_name = opts[:instance_name] || 'instance'
|
16
|
+
@instance_name = opts[:instance_name]
|
17
17
|
@method_signature = method_signature
|
18
18
|
end
|
19
19
|
|
@@ -29,7 +29,11 @@ module Peeky
|
|
29
29
|
|
30
30
|
params = minimal_call_parameters.length.zero? ? '' : "(#{minimal_call_parameters})"
|
31
31
|
|
32
|
-
|
32
|
+
if @instance_name.nil?
|
33
|
+
"#{name}#{params}"
|
34
|
+
else
|
35
|
+
"#{@instance_name}.#{name}#{params}"
|
36
|
+
end
|
33
37
|
end
|
34
38
|
end
|
35
39
|
end
|
data/lib/peeky/version.rb
CHANGED
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
@@ -3,26 +3,16 @@
|
|
3
3
|
require_relative 'lib/peeky/version'
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
# https://piotrmurach.com/articles/writing-a-ruby-gem-specification/
|
7
|
-
spec.required_ruby_version = '>= 2.5'
|
8
6
|
spec.name = 'peeky'
|
9
7
|
spec.version = Peeky::VERSION
|
10
8
|
spec.authors = ['David Cruwys']
|
11
9
|
spec.email = ['david@ideasmen.com.au']
|
12
10
|
|
13
11
|
spec.summary = 'Take a peek into your ruby classes and extract useful meta data'
|
14
|
-
spec.description =
|
15
|
-
Peeky is a Ruby GEM for peaking into ruby classes and extracting meta data.
|
16
|
-
You can use this meta data to recreate classes, interfaces, documentation etc.
|
17
|
-
or use it just to understand the internals of a class.
|
18
|
-
TEXT
|
19
|
-
|
12
|
+
spec.description = 'peeky'
|
20
13
|
spec.homepage = 'http://appydave.com/gems/peeky'
|
21
14
|
spec.license = 'MIT'
|
22
|
-
|
23
|
-
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
24
|
-
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
25
|
-
raise 'RubyGems 2.0 or newer is required to protect against public gem pushes.' unless spec.respond_to?(:metadata)
|
15
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.4.0')
|
26
16
|
|
27
17
|
# spec.metadata['allowed_push_host'] = "Set to 'http://mygemserver.com'"
|
28
18
|
|
@@ -37,15 +27,14 @@ Gem::Specification.new do |spec|
|
|
37
27
|
# Specify which files should be added to the gem when it is released.
|
38
28
|
# The `git ls-files -z` loads the RubyGem files that have been added into git.
|
39
29
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
40
|
-
`git ls-files -z`.split("\x0").reject
|
41
|
-
f.match(%r{^(test|spec|features)/})
|
42
|
-
end
|
30
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
43
31
|
end
|
44
32
|
spec.bindir = 'exe'
|
45
33
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
46
34
|
spec.require_paths = ['lib']
|
35
|
+
|
47
36
|
# spec.extensions = ['ext/peeky/extconf.rb']
|
48
|
-
spec.extra_rdoc_files = ['README.md', 'STORIES.md']
|
37
|
+
spec.extra_rdoc_files = ['README.md', 'STORIES.md', 'USAGE.md']
|
49
38
|
spec.rdoc_options += [
|
50
39
|
'--title', 'peeky by appydave.com',
|
51
40
|
'--main', 'README.md',
|
@@ -53,5 +42,4 @@ Gem::Specification.new do |spec|
|
|
53
42
|
]
|
54
43
|
|
55
44
|
spec.add_dependency 'activesupport'
|
56
|
-
# spec.add_dependency 'tty-box', '~> 0.5.0'
|
57
45
|
end
|
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.
|
4
|
+
version: 0.0.43
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Cruwys
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-10-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -24,10 +24,7 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
description:
|
28
|
-
Peeky is a Ruby GEM for peaking into ruby classes and extracting meta data.
|
29
|
-
You can use this meta data to recreate classes, interfaces, documentation etc.
|
30
|
-
or use it just to understand the internals of a class.
|
27
|
+
description: peeky
|
31
28
|
email:
|
32
29
|
- david@ideasmen.com.au
|
33
30
|
executables: []
|
@@ -35,6 +32,7 @@ extensions: []
|
|
35
32
|
extra_rdoc_files:
|
36
33
|
- README.md
|
37
34
|
- STORIES.md
|
35
|
+
- USAGE.md
|
38
36
|
files:
|
39
37
|
- ".github/workflows/ruby.yml"
|
40
38
|
- ".gitignore"
|
@@ -49,6 +47,7 @@ files:
|
|
49
47
|
- Rakefile
|
50
48
|
- STORIES.md
|
51
49
|
- USAGE.md
|
50
|
+
- USAGE2.md
|
52
51
|
- bin/console
|
53
52
|
- bin/k
|
54
53
|
- bin/kgitsync
|
@@ -60,7 +59,6 @@ files:
|
|
60
59
|
- lib/peeky/api.rb
|
61
60
|
- lib/peeky/attr_info.rb
|
62
61
|
- lib/peeky/class_info.rb
|
63
|
-
- lib/peeky/example/yard_sample.rb
|
64
62
|
- lib/peeky/method_info.rb
|
65
63
|
- lib/peeky/parameter_info.rb
|
66
64
|
- lib/peeky/predicates/attr_reader_predicate.rb
|
@@ -94,14 +92,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
92
|
requirements:
|
95
93
|
- - ">="
|
96
94
|
- !ruby/object:Gem::Version
|
97
|
-
version:
|
95
|
+
version: 2.4.0
|
98
96
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
97
|
requirements:
|
100
98
|
- - ">="
|
101
99
|
- !ruby/object:Gem::Version
|
102
100
|
version: '0'
|
103
101
|
requirements: []
|
104
|
-
rubygems_version: 3.
|
102
|
+
rubygems_version: 3.2.7
|
105
103
|
signing_key:
|
106
104
|
specification_version: 4
|
107
105
|
summary: Take a peek into your ruby classes and extract useful meta data
|
@@ -1,124 +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 (optional)
|
51
|
-
def f_method_with_required_param_and_optional_param(first_name, last_name = nil)
|
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 (optional)
|
58
|
-
# @param age [String] age (optional)
|
59
|
-
def g_method_with_required_param_and_two_optional_params(first_name, last_name = nil, age = nil)
|
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: <value for salutation> (optional)
|
98
|
-
def n_method_with_key_value_param_required_and_optional_key_value(last_name:, salutation: nil)
|
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 [String] bbb (optional)
|
115
|
-
# @param ccc [Array<Object>] *ccc - list of ccc
|
116
|
-
# @param ddd [String] ddd: <value for ddd> (required)
|
117
|
-
# @param eee [String] eee: <value for eee> (optional)
|
118
|
-
# @param fff [<key: value>...] **fff - list of key/values
|
119
|
-
# @param ggg [Block] &ggg
|
120
|
-
def z_complex(aaa, bbb = nil, *ccc, ddd:, eee: nil, **fff, &ggg)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|