core_docs 0.9.0
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 +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +13 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +3 -0
- data/LICENSE +25 -0
- data/README.md +18 -0
- data/Rakefile +107 -0
- data/core_docs.gemspec +27 -0
- data/lib/core_docs.rb +228 -0
- data/lib/core_docs/core_docs_20/checksums +262 -0
- data/lib/core_docs/core_docs_20/object_types +0 -0
- data/lib/core_docs/core_docs_20/objects/root.dat +0 -0
- data/lib/core_docs/core_docs_20/proxy_types +0 -0
- data/lib/core_docs/core_docs_21/checksums +290 -0
- data/lib/core_docs/core_docs_21/object_types +0 -0
- data/lib/core_docs/core_docs_21/objects/root.dat +0 -0
- data/lib/core_docs/core_docs_21/proxy_types +0 -0
- data/lib/core_docs/core_docs_22/checksums +474 -0
- data/lib/core_docs/core_docs_22/object_types +0 -0
- data/lib/core_docs/core_docs_22/objects/root.dat +0 -0
- data/lib/core_docs/core_docs_22/proxy_types +0 -0
- data/lib/core_docs/version.rb +3 -0
- data/spec/core_docs_spec.rb +199 -0
- data/spec/gem_with_cext/gems/ext/extconf.rb +2 -0
- data/spec/gem_with_cext/gems/ext/sample.c +17 -0
- data/spec/gem_with_cext/gems/lib/sample.rb +18 -0
- data/spec/gem_with_cext/gems/sample.rb +4 -0
- data/spec/helper.rb +11 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ef9c9b9dc66c55c7cfa891c263014f2c2e76d7eb
|
4
|
+
data.tar.gz: 987df53f273c819846120fcc6f09b8274cc1cbec
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: db62934c09ab1be4ca56cc44a93a95e1f1908a3cc41259cd49044d4cc5d72e8a5ce8d263ba94691ef76aef61db6c8259e81fb04aeb1eaef20a4f7c10b7752d5e
|
7
|
+
data.tar.gz: b23f4960d820ab46968dca9d17bb8ab6ff2644ee9e393f569df1228ea1a61e6282194ce847c2571ccdbece946f95dce8965863680409be0cfba81c5de1dbff5d
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--markup markdown
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
License
|
2
|
+
-------
|
3
|
+
|
4
|
+
(The MIT License)
|
5
|
+
|
6
|
+
Copyright (c) 2013 John Mair (banisterfiend)
|
7
|
+
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
9
|
+
a copy of this software and associated documentation files (the
|
10
|
+
'Software'), to deal in the Software without restriction, including
|
11
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
12
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
13
|
+
permit persons to whom the Software is furnished to do so, subject to
|
14
|
+
the following conditions:
|
15
|
+
|
16
|
+
The above copyright notice and this permission notice shall be
|
17
|
+
included in all copies or substantial portions of the Software.
|
18
|
+
|
19
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
20
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
21
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
22
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
23
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
24
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
25
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
MRI Core Docs
|
2
|
+
=============
|
3
|
+
|
4
|
+
Core Docs is a fork from [pry-doc](https://github.com/pry/pry-doc) that separates its functionality from the pry repl.
|
5
|
+
|
6
|
+
Experimental, don't consider this battle-proof.
|
7
|
+
|
8
|
+
|
9
|
+
TODO
|
10
|
+
----
|
11
|
+
|
12
|
+
Polish and get specs to run.
|
13
|
+
|
14
|
+
|
15
|
+
License
|
16
|
+
-------
|
17
|
+
|
18
|
+
The project uses the MIT Licencse. See LICENSE file for more information.
|
data/Rakefile
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
dlext = RbConfig::CONFIG['DLEXT']
|
2
|
+
direc = File.dirname(__FILE__)
|
3
|
+
|
4
|
+
PROJECT_NAME = "core_docs"
|
5
|
+
|
6
|
+
require 'latest_ruby'
|
7
|
+
require 'rake/clean'
|
8
|
+
require "#{direc}/lib/#{PROJECT_NAME}/version"
|
9
|
+
|
10
|
+
desc "run tests"
|
11
|
+
task :test do
|
12
|
+
sh "bacon -k #{direc}/spec/core_docs_spec.rb"
|
13
|
+
end
|
14
|
+
task :spec => :test
|
15
|
+
|
16
|
+
task :default => :test
|
17
|
+
|
18
|
+
desc "reinstall gem"
|
19
|
+
task :reinstall => :gems do
|
20
|
+
sh "gem uninstall core_docs" rescue nil
|
21
|
+
sh "gem install #{direc}/pkg/core_docs-#{CoreDocs::VERSION}.gem"
|
22
|
+
end
|
23
|
+
|
24
|
+
desc "build all platform gems at once"
|
25
|
+
task :gems => :rmgems do
|
26
|
+
mkdir_p "pkg"
|
27
|
+
sh 'gem build *.gemspec'
|
28
|
+
mv "core_docs-#{CoreDocs::VERSION}.gem", "pkg"
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "remove all platform gems"
|
32
|
+
task :rmgems do
|
33
|
+
rm_rf 'pkg'
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "Build gemspec"
|
37
|
+
task :gemspec => "ruby:gemspec"
|
38
|
+
|
39
|
+
desc "Show version"
|
40
|
+
task :version do
|
41
|
+
puts "CoreDocs version: #{CoreDocs::VERSION}"
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "build and push latest gems"
|
45
|
+
task :pushgems => :gems do
|
46
|
+
chdir("#{direc}/pkg") do
|
47
|
+
Dir["*.gem"].each do |gemfile|
|
48
|
+
sh "gem push #{gemfile}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def download_ruby(ruby)
|
54
|
+
system "mkdir rubies"
|
55
|
+
system "wget #{ ruby.link } --directory-prefix=rubies --no-clobber"
|
56
|
+
File.join('rubies', ruby.filename)
|
57
|
+
end
|
58
|
+
|
59
|
+
def unpackage_ruby(path)
|
60
|
+
system "mkdir rubies/ruby"
|
61
|
+
system "tar xzvf #{ path } --directory=rubies/ruby"
|
62
|
+
end
|
63
|
+
|
64
|
+
def cd_into_ruby
|
65
|
+
Dir.chdir(Dir['rubies/ruby/*'].first)
|
66
|
+
end
|
67
|
+
|
68
|
+
def generate_yard
|
69
|
+
system %{
|
70
|
+
bash -c "paste <(find . -maxdepth 1 -name '*.c') <(find ext -name '*.c') |
|
71
|
+
xargs yardoc --no-output"
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
def replace_existing_docs(ver)
|
76
|
+
target_dir = "../../../lib/core_docs/core_docs_#{ ver }"
|
77
|
+
system %|mkdir -p #{ target_dir } && cp -r .yardoc/* #{ target_dir }|
|
78
|
+
Dir.chdir(File.expand_path(File.dirname(__FILE__)))
|
79
|
+
end
|
80
|
+
|
81
|
+
def clean_up
|
82
|
+
system "rm -rf rubies"
|
83
|
+
end
|
84
|
+
|
85
|
+
def generate_docs_for(ruby_ver, latest_ruby)
|
86
|
+
path = download_ruby(latest_ruby)
|
87
|
+
unpackage_ruby(path)
|
88
|
+
cd_into_ruby
|
89
|
+
generate_yard
|
90
|
+
replace_existing_docs(ruby_ver)
|
91
|
+
clean_up
|
92
|
+
end
|
93
|
+
|
94
|
+
desc "Generate the latest Ruby 2.0 docs"
|
95
|
+
task "gen20" do
|
96
|
+
generate_docs_for('20', Latest.ruby20)
|
97
|
+
end
|
98
|
+
|
99
|
+
desc "Generate the latest Ruby 2.1 docs"
|
100
|
+
task "gen21" do
|
101
|
+
generate_docs_for('21', Latest.ruby21)
|
102
|
+
end
|
103
|
+
|
104
|
+
desc "Generate the latest Ruby 2.2 docs"
|
105
|
+
task "gen22" do
|
106
|
+
generate_docs_for('22', Latest.ruby22)
|
107
|
+
end
|
data/core_docs.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require './lib/core_docs/version.rb'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "core_docs"
|
5
|
+
s.version = CoreDocs::VERSION
|
6
|
+
|
7
|
+
s.authors = ["John Mair (banisterfiend)", "Jan Lelis (non-pry version)"]
|
8
|
+
s.email = ["jrmair@gmail.com", "mail@janlelis.de"]
|
9
|
+
s.summary = 'Provides YARD and extended documentation support for Pry'
|
10
|
+
s.description = <<DESCR
|
11
|
+
Pry Doc is a Pry REPL plugin. It provides extended documentation support for the
|
12
|
+
REPL by means of improving the `show-doc` and `show-source` commands. With help
|
13
|
+
of the plugin the commands are be able to display the source code and the docs
|
14
|
+
of Ruby methods and classes implemented in C.
|
15
|
+
documentation
|
16
|
+
DESCR
|
17
|
+
s.homepage = "https://github.com/janlelis/core_docs"
|
18
|
+
s.license = 'MIT'
|
19
|
+
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
|
23
|
+
s.required_ruby_version = "~> 2.0"
|
24
|
+
s.add_dependency 'yard', "~> 0.8"
|
25
|
+
s.add_development_dependency 'latest_ruby', "~> 0.0"
|
26
|
+
s.add_development_dependency 'bacon', "~> 1.1"
|
27
|
+
end
|
data/lib/core_docs.rb
ADDED
@@ -0,0 +1,228 @@
|
|
1
|
+
# based on pry-doc.rb
|
2
|
+
# (C) John Mair (banisterfiend); MIT license
|
3
|
+
|
4
|
+
direc = File.dirname(__FILE__)
|
5
|
+
|
6
|
+
require "#{direc}/core_docs/version"
|
7
|
+
require "yard"
|
8
|
+
|
9
|
+
module CoreDocs
|
10
|
+
def self.load_yardoc(version)
|
11
|
+
path = "#{File.dirname(__FILE__)}/core_docs/core_docs_#{ version }"
|
12
|
+
YARD::Registry.load_yardoc(path)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
case RUBY_VERSION
|
17
|
+
when /\A2\.1/
|
18
|
+
CoreDocs.load_yardoc('21')
|
19
|
+
else
|
20
|
+
CoreDocs.load_yardoc('20')
|
21
|
+
end
|
22
|
+
|
23
|
+
# do not use pry-doc if rbx is active
|
24
|
+
# if !Object.const_defined?(:RUBY_ENGINE) || RUBY_ENGINE !~ /rbx/
|
25
|
+
# self.config.has_pry_doc = true
|
26
|
+
# end
|
27
|
+
|
28
|
+
module CoreDocs
|
29
|
+
module MethodInfo
|
30
|
+
|
31
|
+
# Convert a method object into the `Class#method` string notation.
|
32
|
+
# @param [Method, UnboundMethod] meth
|
33
|
+
# @return [String] The method in string receiver notation.
|
34
|
+
# @note This mess is needed in order to support all the modern Rubies. YOU
|
35
|
+
# must figure out a better way to distinguish between class methods and
|
36
|
+
# instance methods.
|
37
|
+
def self.receiver_notation_for(meth)
|
38
|
+
match = meth.inspect.match(/\A#<(?:Unbound)?Method: (.+)([#\.].+)>\z/)
|
39
|
+
owner = meth.owner.to_s.sub(/#<.+?:(.+?)>/, '\1')
|
40
|
+
name = match[2]
|
41
|
+
name.sub!('#', '.') if match[1] =~ /\A#<Class:/
|
42
|
+
owner + name
|
43
|
+
end
|
44
|
+
|
45
|
+
# Retrives aliases of a method
|
46
|
+
# @param [Method, UnboundMethod] meth The method object.
|
47
|
+
# @return [Array] The aliases of a method if it exists
|
48
|
+
# otherwise, return empty array
|
49
|
+
def self.aliases(meth)
|
50
|
+
# host = is_singleton?(meth) ? meth.receiver : meth.owner
|
51
|
+
# method_type = is_singleton?(meth) ? :method : :instance_method
|
52
|
+
|
53
|
+
# methods = Pry::Method.send(:all_from_common, host, method_type, false).
|
54
|
+
# map { |m| m.instance_variable_get(:@method) }
|
55
|
+
|
56
|
+
# methods.select { |m| host.send(method_type,m.name) == host.send(method_type,meth.name) }.
|
57
|
+
# reject { |m| m.name == meth.name }.
|
58
|
+
# map { |m| host.send(method_type,m.name) }
|
59
|
+
[]
|
60
|
+
end
|
61
|
+
|
62
|
+
# Checks whether method is a singleton (i.e class method)
|
63
|
+
# @param [Method, UnboundMethod] meth
|
64
|
+
# @param [Boolean] true if singleton
|
65
|
+
def self.is_singleton?(meth)
|
66
|
+
receiver_notation_for(meth).include?('.')
|
67
|
+
end
|
68
|
+
|
69
|
+
# Check whether the file containing the method is already cached.
|
70
|
+
# @param [Method, UnboundMethod] meth The method object.
|
71
|
+
# @return [Boolean] Whether the method is cached.
|
72
|
+
def self.cached?(meth)
|
73
|
+
!!registry_lookup(meth)
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.registry_lookup(meth)
|
77
|
+
obj = YARD::Registry.at(receiver_notation_for(meth))
|
78
|
+
if obj.nil?
|
79
|
+
if !(aliases = aliases(meth)).empty?
|
80
|
+
obj = YARD::Registry.at(receiver_notation_for(aliases.first))
|
81
|
+
elsif meth.owner == Kernel
|
82
|
+
# YARD thinks that some methods are on Object when
|
83
|
+
# they're actually on Kernel; so try again on Object if Kernel fails.
|
84
|
+
obj = YARD::Registry.at("Object##{meth.name}")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
obj
|
88
|
+
end
|
89
|
+
|
90
|
+
# Retrieve the YARD object that contains the method data.
|
91
|
+
# @param [Method, UnboundMethod] meth The method object.
|
92
|
+
# @return [YARD::CodeObjects::MethodObject] The YARD data for the method.
|
93
|
+
def self.info_for(meth)
|
94
|
+
cache(meth)
|
95
|
+
registry_lookup(meth)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Determine whether a method is an eval method.
|
99
|
+
# @return [Boolean] Whether the method is an eval method.
|
100
|
+
def self.is_eval_method?(meth)
|
101
|
+
file, _ = meth.source_location
|
102
|
+
if file =~ /(\(.*\))|<.*>/
|
103
|
+
true
|
104
|
+
else
|
105
|
+
false
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Attempts to find the c source files if method belongs to a gem
|
110
|
+
# and use YARD to parse and cache the source files for display
|
111
|
+
#
|
112
|
+
# @param [Method, UnboundMethod] meth The method object.
|
113
|
+
def self.parse_and_cache_if_gem_cext(meth)
|
114
|
+
if gem_dir = find_gem_dir(meth)
|
115
|
+
if c_files_found?(gem_dir)
|
116
|
+
warn "Scanning and caching *.c files..."
|
117
|
+
YARD.parse("#{gem_dir}/**/*.c")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# @param [String] root directory path of gem that method belongs to
|
123
|
+
# @return [Boolean] true if c files exist?
|
124
|
+
def self.c_files_found?(gem_dir)
|
125
|
+
Dir.glob("#{gem_dir}/**/*.c").count > 0
|
126
|
+
end
|
127
|
+
|
128
|
+
# @return [Object] The host of the method (receiver or owner).
|
129
|
+
def self.method_host(meth)
|
130
|
+
is_singleton?(meth) && Module === meth.receiver ? meth.receiver : meth.owner
|
131
|
+
end
|
132
|
+
|
133
|
+
# FIXME: this is unnecessarily limited to ext/ and lib/ folders
|
134
|
+
# @return [String] The root folder of a given gem directory.
|
135
|
+
def self.gem_root(dir)
|
136
|
+
if index = dir.rindex(/\/(?:lib|ext)(?:\/|$)/)
|
137
|
+
dir[0..index-1]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# @param [Method, UnboundMethod] meth The method object.
|
142
|
+
# @return [String] root directory path of gem that method belongs to,
|
143
|
+
# nil if could not be found
|
144
|
+
def self.find_gem_dir(meth)
|
145
|
+
# host = method_host(meth)
|
146
|
+
|
147
|
+
# begin
|
148
|
+
# host_source_location, _ = WrappedModule.new(host).source_location
|
149
|
+
# break if host_source_location != nil
|
150
|
+
# return unless host.name
|
151
|
+
# host = eval(host.namespace_name)
|
152
|
+
# end while host
|
153
|
+
|
154
|
+
# # we want to exclude all source_locations that aren't gems (i.e
|
155
|
+
# # stdlib)
|
156
|
+
# if host_source_location && host_source_location =~ %r{/gems/}
|
157
|
+
# gem_root(host_source_location)
|
158
|
+
# else
|
159
|
+
|
160
|
+
# the WrappedModule approach failed, so try our backup approach
|
161
|
+
gem_dir_from_method(meth)
|
162
|
+
# end
|
163
|
+
end
|
164
|
+
|
165
|
+
# Try to guess what the gem name will be based on the name of the module.
|
166
|
+
# We try a few approaches here depending on the `guess` parameter.
|
167
|
+
# @param [String] name The name of the module.
|
168
|
+
# @param [Fixnum] guess The current guessing approach to use.
|
169
|
+
# @return [String, nil] The guessed gem name, or `nil` if out of guesses.
|
170
|
+
def self.guess_gem_name_from_module_name(name, guess)
|
171
|
+
case guess
|
172
|
+
when 0
|
173
|
+
name.downcase
|
174
|
+
when 1
|
175
|
+
name.scan(/[A-Z][a-z]+/).map(&:downcase).join('_')
|
176
|
+
when 2
|
177
|
+
name.scan(/[A-Z][a-z]+/).map(&:downcase).join('_').sub("_", "-")
|
178
|
+
when 3
|
179
|
+
name.scan(/[A-Z][a-z]+/).map(&:downcase).join('-')
|
180
|
+
when 4
|
181
|
+
name
|
182
|
+
else
|
183
|
+
nil
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Try to recover the gem directory of a gem based on a method object.
|
188
|
+
# @param [Method, UnboundMethod] meth The method object.
|
189
|
+
# @return [String, nil] The located gem directory.
|
190
|
+
def self.gem_dir_from_method(meth)
|
191
|
+
guess = 0
|
192
|
+
|
193
|
+
host = method_host(meth)
|
194
|
+
return unless host.name
|
195
|
+
root_module_name = host.name.split("::").first
|
196
|
+
while gem_name = guess_gem_name_from_module_name(root_module_name, guess)
|
197
|
+
matches = $LOAD_PATH.grep %r{/gems/#{gem_name}} if !gem_name.empty?
|
198
|
+
if matches && matches.any?
|
199
|
+
return gem_root(matches.first)
|
200
|
+
else
|
201
|
+
guess += 1
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
nil
|
206
|
+
end
|
207
|
+
|
208
|
+
# Cache the file that holds the method or return immediately if file is
|
209
|
+
# already cached. Return if the method cannot be cached -
|
210
|
+
# i.e is a C stdlib method.
|
211
|
+
# @param [Method, UnboundMethod] meth The method object.
|
212
|
+
def self.cache(meth)
|
213
|
+
file, _ = meth.source_location
|
214
|
+
|
215
|
+
return if is_eval_method?(meth)
|
216
|
+
return if cached?(meth)
|
217
|
+
|
218
|
+
if !file
|
219
|
+
parse_and_cache_if_gem_cext(meth)
|
220
|
+
return
|
221
|
+
end
|
222
|
+
|
223
|
+
log.enter_level(Logger::FATAL) do
|
224
|
+
YARD.parse(file)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|