yard-link_stdlib 0.1.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/LICENSE.txt +28 -0
- data/NAME +1 -0
- data/README.md +39 -0
- data/VERSION +1 -0
- data/bin/make_map.rb +107 -0
- data/lib/yard-link_stdlib.rb +21 -0
- data/lib/yard/cli/link_stdlib.rb +147 -0
- data/lib/yard/link_stdlib.rb +212 -0
- data/lib/yard/link_stdlib/dump.rb +74 -0
- data/lib/yard/link_stdlib/html_helper.rb +133 -0
- data/lib/yard/link_stdlib/object_map.rb +217 -0
- data/lib/yard/link_stdlib/ruby_source.rb +189 -0
- data/lib/yard/link_stdlib/ruby_version.rb +233 -0
- data/lib/yard/link_stdlib/version.rb +101 -0
- data/maps/ruby-2.3.0.json.gz +0 -0
- data/maps/ruby-2.4.0.json.gz +0 -0
- data/maps/ruby-2.5.0.json.gz +0 -0
- metadata +176 -0
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
|
5
|
+
# Namespace
|
6
|
+
# ========================================================================
|
7
|
+
|
8
|
+
module YARD
|
9
|
+
module LinkStdlib
|
10
|
+
|
11
|
+
|
12
|
+
# Definitions
|
13
|
+
# ========================================================================
|
14
|
+
|
15
|
+
# Dump a hash of values as a `debug`-level log message (`log` is a global
|
16
|
+
# function when you're hangin' in the YARD).
|
17
|
+
#
|
18
|
+
# @example Dump values with a message
|
19
|
+
# dump "There was a problem with the ", obj, "object!",
|
20
|
+
# value_a: value_a,
|
21
|
+
# value_b: value_b
|
22
|
+
#
|
23
|
+
# @example Dump values without a message
|
24
|
+
# dump value_a: value_a, value_b: value_b
|
25
|
+
#
|
26
|
+
# @param [Array<String | Object>] message
|
27
|
+
# Optional log message. Entries will be space-joined to form the message
|
28
|
+
# string: strings will be left as-is, and other objects will be
|
29
|
+
# stringified by calling their `#inspect` method. See examples.
|
30
|
+
#
|
31
|
+
# @param [Hash<Symbol, Object>] values
|
32
|
+
# Map of names to values to dump.
|
33
|
+
#
|
34
|
+
# @return
|
35
|
+
# Whatever `log.debug` returns.
|
36
|
+
#
|
37
|
+
def self.dump *message, **values
|
38
|
+
|
39
|
+
max_name_length = values.
|
40
|
+
keys.
|
41
|
+
map { |name| name.to_s.length }.
|
42
|
+
max
|
43
|
+
|
44
|
+
values_str = values.
|
45
|
+
map { |name, value|
|
46
|
+
name_str = "%-#{ max_name_length + 2 }s" % "#{ name }:"
|
47
|
+
|
48
|
+
" #{ name_str } #{ value.inspect } (#{ value.class })"
|
49
|
+
}.
|
50
|
+
join( "\n" )
|
51
|
+
|
52
|
+
message_str = message.
|
53
|
+
map { |part|
|
54
|
+
case part
|
55
|
+
when String
|
56
|
+
part
|
57
|
+
else
|
58
|
+
part.inspect
|
59
|
+
end
|
60
|
+
}.
|
61
|
+
join( " " )
|
62
|
+
|
63
|
+
log_str = "Values:\n\n#{ values_str }\n"
|
64
|
+
log_str = "#{ message_str }\n\n#{ log_str }" unless message_str.empty?
|
65
|
+
|
66
|
+
log.debug "yard-link_stdlib: #{ log_str }"
|
67
|
+
end # .dump
|
68
|
+
|
69
|
+
|
70
|
+
# /Namespace
|
71
|
+
# ========================================================================
|
72
|
+
|
73
|
+
end # module LinkStdlib
|
74
|
+
end # module YARD
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
# Requirements
|
5
|
+
# ========================================================================
|
6
|
+
|
7
|
+
# Stdlib
|
8
|
+
# ------------------------------------------------------------------------
|
9
|
+
|
10
|
+
require 'zlib'
|
11
|
+
|
12
|
+
# Deps
|
13
|
+
# ------------------------------------------------------------------------
|
14
|
+
|
15
|
+
require 'yard'
|
16
|
+
|
17
|
+
# Project / Package
|
18
|
+
# ------------------------------------------------------------------------
|
19
|
+
|
20
|
+
require_relative './dump'
|
21
|
+
require_relative './ruby_version'
|
22
|
+
require_relative './object_map'
|
23
|
+
|
24
|
+
|
25
|
+
# Namespace
|
26
|
+
# ========================================================================
|
27
|
+
|
28
|
+
module YARD
|
29
|
+
module LinkStdlib
|
30
|
+
|
31
|
+
|
32
|
+
# Definitions
|
33
|
+
# ========================================================================
|
34
|
+
|
35
|
+
# A helper module to add to {YARD::Templates::Template.extra_includes} to
|
36
|
+
# handle linking stdlib references.
|
37
|
+
#
|
38
|
+
# @see https://www.rubydoc.info/gems/yard/YARD%2FTemplates%2FTemplate.extra_includes
|
39
|
+
#
|
40
|
+
module HtmlHelper
|
41
|
+
|
42
|
+
# The {Proc} we pass to
|
43
|
+
#
|
44
|
+
# @return [Proc]
|
45
|
+
#
|
46
|
+
INCLUDE_FILTER = proc do |options|
|
47
|
+
HtmlHelper if options.format == :html
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
# The only real meat of this whole gem - hook into object linking.
|
52
|
+
#
|
53
|
+
# We link to the stdlib if:
|
54
|
+
#
|
55
|
+
# 1. We didn't link to anything else (local stuff take precedence).
|
56
|
+
# 2. We can find a match for the reference.
|
57
|
+
#
|
58
|
+
# @see https://www.rubydoc.info/gems/yard/YARD/Templates/Helpers/HtmlHelper#link_object-instance_method
|
59
|
+
#
|
60
|
+
# @param [YARD::CodeObjects::Base] obj
|
61
|
+
# The object to link to.
|
62
|
+
#
|
63
|
+
# @param [String?] title
|
64
|
+
# Optional title to display the link as.
|
65
|
+
#
|
66
|
+
# @param [nil | ?] anchor
|
67
|
+
# Not sure... not doc'd in YARD.
|
68
|
+
#
|
69
|
+
# @param [Boolean] relative
|
70
|
+
# Again, not sure... not doc'd in YARD, but seems like a boolean.
|
71
|
+
#
|
72
|
+
# @return [String]
|
73
|
+
# The HTML source for the link.
|
74
|
+
#
|
75
|
+
def link_object obj, title = nil, anchor = nil, relative = true
|
76
|
+
# See what the super method can do...
|
77
|
+
super_link = super
|
78
|
+
|
79
|
+
# Bail out unless `super` returned a {String}, which I'm guessing would be
|
80
|
+
# `nil`, but not sure.
|
81
|
+
unless super_link.is_a?( String )
|
82
|
+
LinkStdlib.dump "Object not linkable",
|
83
|
+
obj: obj,
|
84
|
+
super_link: super_link
|
85
|
+
return super_link
|
86
|
+
end
|
87
|
+
|
88
|
+
LinkStdlib.dump "Object *may* be linkable!",
|
89
|
+
obj: obj,
|
90
|
+
super_link: super_link
|
91
|
+
|
92
|
+
# `key` is what we gonna look up in the stdlib...
|
93
|
+
key = super_link
|
94
|
+
|
95
|
+
# Strip off any leading `::`
|
96
|
+
key = key[2..-1] if key.start_with?( '::' )
|
97
|
+
|
98
|
+
# Stdlib rdoc uses `ClassOrModule::class_method` format for class methods,
|
99
|
+
# so we want to convert to that
|
100
|
+
stdlib_key = key.sub /\.(\w+[\?\!]?)\z/, '::\1'
|
101
|
+
|
102
|
+
if ( path = ObjectMap.current.data[ stdlib_key ] )
|
103
|
+
LinkStdlib.dump "Matched stdlib link!",
|
104
|
+
path: path,
|
105
|
+
key: key,
|
106
|
+
stdlib_key: stdlib_key
|
107
|
+
|
108
|
+
version = LinkStdlib::RubyVersion.minor
|
109
|
+
|
110
|
+
[
|
111
|
+
%{<a href="https://docs.ruby-lang.org/en/#{ version }/#{ path }">},
|
112
|
+
key,
|
113
|
+
%{</a>},
|
114
|
+
].join ''
|
115
|
+
|
116
|
+
else
|
117
|
+
LinkStdlib.dump "Got nada.",
|
118
|
+
super_link: super_link
|
119
|
+
|
120
|
+
super_link
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
end # #link_object
|
125
|
+
|
126
|
+
end # module HtmlHelper
|
127
|
+
|
128
|
+
|
129
|
+
# /Namespace
|
130
|
+
# ========================================================================
|
131
|
+
|
132
|
+
end # module LinkStdlib
|
133
|
+
end # module YARD
|
@@ -0,0 +1,217 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
|
5
|
+
# Requirements
|
6
|
+
# ========================================================================
|
7
|
+
|
8
|
+
# Stdlib
|
9
|
+
# ----------------------------------------------------------------------------
|
10
|
+
|
11
|
+
# Encode object maps in JSON... it's just super easy for everything, and
|
12
|
+
# gzip should take care of any size concerns.
|
13
|
+
require 'json'
|
14
|
+
|
15
|
+
# Good ol' mkdir_p...
|
16
|
+
require 'fileutils'
|
17
|
+
|
18
|
+
# Store the JSON-encoded maps compressed
|
19
|
+
require 'zlib'
|
20
|
+
|
21
|
+
|
22
|
+
# Project / Package
|
23
|
+
# ------------------------------------------------------------------------
|
24
|
+
|
25
|
+
# We need {YARD::LinkStdlib::ROOT} to find `//tmp`
|
26
|
+
require_relative './version'
|
27
|
+
|
28
|
+
# Need to be able to {RubySource.ensure} we have source code we need
|
29
|
+
require_relative './ruby_source'
|
30
|
+
|
31
|
+
|
32
|
+
# Namespace
|
33
|
+
# ========================================================================
|
34
|
+
|
35
|
+
module YARD
|
36
|
+
module LinkStdlib
|
37
|
+
|
38
|
+
|
39
|
+
# Definitions
|
40
|
+
# ========================================================================
|
41
|
+
|
42
|
+
|
43
|
+
class ObjectMap
|
44
|
+
|
45
|
+
# Mixins
|
46
|
+
# ==========================================================================
|
47
|
+
|
48
|
+
include Comparable
|
49
|
+
|
50
|
+
|
51
|
+
# Class Variables
|
52
|
+
# ==========================================================================
|
53
|
+
|
54
|
+
@@data_dir = LinkStdlib::ROOT.join( 'maps' ).tap { |path|
|
55
|
+
FileUtils.mkdir_p( path ) unless path.exist?
|
56
|
+
}
|
57
|
+
|
58
|
+
@@current = nil
|
59
|
+
|
60
|
+
|
61
|
+
# Class Methods
|
62
|
+
# ========================================================================
|
63
|
+
|
64
|
+
def self.data_dir= path
|
65
|
+
expanded = Pathname.new( path ).expand_path
|
66
|
+
|
67
|
+
unless expanded.directory?
|
68
|
+
raise ArgumentError,
|
69
|
+
"Custom ObjectMap.data_dir must expand to an existing directory," +
|
70
|
+
"try creating it first? Received #{ path.inspect }, expanded to " +
|
71
|
+
expanded.to_s.inspect
|
72
|
+
end
|
73
|
+
|
74
|
+
@@data_dir = expanded
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
def self.data_dir
|
79
|
+
@@data_dir
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def self.current
|
84
|
+
version = RubyVersion.get
|
85
|
+
|
86
|
+
if @@current.nil? || @@current.version != version
|
87
|
+
@@current = new( version ).make
|
88
|
+
end
|
89
|
+
|
90
|
+
@@current
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
# @todo Document list method.
|
96
|
+
#
|
97
|
+
# @param [type] arg_name
|
98
|
+
# @todo Add name param description.
|
99
|
+
#
|
100
|
+
# @return [return_type]
|
101
|
+
# @todo Document return value.
|
102
|
+
#
|
103
|
+
def self.list
|
104
|
+
data_dir.entries.
|
105
|
+
select { |filename| filename.to_s =~ /\Aruby\-(\d+\.)+json\.gz\z/ }.
|
106
|
+
map { |filename|
|
107
|
+
new File.basename( filename.to_s, '.json.gz' ).sub( /\Aruby\-/, '' )
|
108
|
+
}.
|
109
|
+
sort
|
110
|
+
end # .list
|
111
|
+
|
112
|
+
|
113
|
+
# def self.cache key, &load
|
114
|
+
# @cache ||= {}
|
115
|
+
|
116
|
+
# unless @cache.key? key
|
117
|
+
# @cache[key] = load.call
|
118
|
+
# end
|
119
|
+
|
120
|
+
# @cache[key]
|
121
|
+
# end
|
122
|
+
|
123
|
+
|
124
|
+
# def self.get version = LinkStdlib::RubyVersion.get, make: true
|
125
|
+
# cache version do
|
126
|
+
# make( version ) if make
|
127
|
+
# load version
|
128
|
+
# end
|
129
|
+
# end
|
130
|
+
|
131
|
+
|
132
|
+
# Ruby version.
|
133
|
+
#
|
134
|
+
# @return [Gem::Version]
|
135
|
+
#
|
136
|
+
attr_reader :version
|
137
|
+
|
138
|
+
|
139
|
+
def initialize version
|
140
|
+
@version = Gem::Version.new version
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
def filename
|
145
|
+
@filename ||= "ruby-#{ version }.json.gz"
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
def path
|
150
|
+
@path ||= self.class.data_dir.join filename
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
# Is the object map present for this {#version}?
|
155
|
+
#
|
156
|
+
# @return [Boolean]
|
157
|
+
#
|
158
|
+
def present?
|
159
|
+
path.exist?
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
def source
|
164
|
+
@source ||= RubySource.new version
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
def make force: false
|
169
|
+
# Bail unless forced or the map is not present
|
170
|
+
if force
|
171
|
+
log.info "FORCE making object map for Ruby #{ version }..."
|
172
|
+
elsif !present?
|
173
|
+
log.info "Making object map for Ruby #{ version }..."
|
174
|
+
else
|
175
|
+
log.info "Object map for Ruby #{ version } is present."
|
176
|
+
return self
|
177
|
+
end
|
178
|
+
|
179
|
+
# Make sure we have the source files in place
|
180
|
+
source.ensure
|
181
|
+
|
182
|
+
# Invoke the build script
|
183
|
+
LinkStdlib.system! \
|
184
|
+
LinkStdlib::ROOT.join( 'bin', 'make_map.rb' ).to_s,
|
185
|
+
source.src_path.to_s,
|
186
|
+
path.to_s
|
187
|
+
|
188
|
+
log.info "Made object map for Ruby #{ version }."
|
189
|
+
|
190
|
+
self
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
def data reload: false
|
195
|
+
if reload || @data.nil?
|
196
|
+
@data = Zlib::GzipReader.open path do |gz|
|
197
|
+
JSON.load gz.read
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
@data
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
def <=> other
|
206
|
+
version <=> other.version
|
207
|
+
end
|
208
|
+
|
209
|
+
|
210
|
+
end # class ObjectMap
|
211
|
+
|
212
|
+
|
213
|
+
# /Namespace
|
214
|
+
# ========================================================================
|
215
|
+
|
216
|
+
end # module LinkStdlib
|
217
|
+
end # module YARD
|
@@ -0,0 +1,189 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
|
5
|
+
# Requirements
|
6
|
+
# ========================================================================
|
7
|
+
|
8
|
+
# Stdlib
|
9
|
+
# ----------------------------------------------------------------------------
|
10
|
+
|
11
|
+
require 'net/http'
|
12
|
+
require 'uri'
|
13
|
+
|
14
|
+
|
15
|
+
# Namespace
|
16
|
+
# ========================================================================
|
17
|
+
|
18
|
+
module YARD
|
19
|
+
module LinkStdlib
|
20
|
+
|
21
|
+
|
22
|
+
# Definitions
|
23
|
+
# ========================================================================
|
24
|
+
|
25
|
+
# Light utility object around a Ruby {Gem::Version} used to download and
|
26
|
+
# extract it's source code to the {LinkStdlib.tmp_dir}.
|
27
|
+
#
|
28
|
+
class RubySource
|
29
|
+
|
30
|
+
# Mixins
|
31
|
+
# ========================================================================
|
32
|
+
|
33
|
+
include Comparable
|
34
|
+
|
35
|
+
|
36
|
+
# Class Methods
|
37
|
+
# ============================================================================
|
38
|
+
|
39
|
+
# Ensure the version's source is downloaded and extracted.
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
# YARD::LinkStdlib::RubySource.ensure '2.5.1'
|
43
|
+
#
|
44
|
+
# @param [Gem::Version || #to_s] version
|
45
|
+
# The Ruby version you need present.
|
46
|
+
#
|
47
|
+
# @return [RubySource]
|
48
|
+
# The utility object instance.
|
49
|
+
#
|
50
|
+
def self.ensure version
|
51
|
+
new( version ).ensure
|
52
|
+
end # .ensure
|
53
|
+
|
54
|
+
|
55
|
+
def self.list
|
56
|
+
LinkStdlib.tmp_dir.entries.
|
57
|
+
select { |filename|
|
58
|
+
filename.to_s =~ /\Aruby\-\d+\_\d+\_\d+\z/
|
59
|
+
}.
|
60
|
+
map { |filename|
|
61
|
+
new filename.to_s.sub( /\Aruby\-/, '' ).gsub( '_', '.' )
|
62
|
+
}.
|
63
|
+
sort
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
# Ruby version.
|
68
|
+
#
|
69
|
+
# @return [Gem::Version]
|
70
|
+
#
|
71
|
+
attr_reader :version
|
72
|
+
|
73
|
+
|
74
|
+
# Construction
|
75
|
+
# ========================================================================
|
76
|
+
|
77
|
+
# Make a new instance for a version.
|
78
|
+
#
|
79
|
+
# @param [Gem::Version || #to_s] version
|
80
|
+
# The Ruby version to work with.
|
81
|
+
#
|
82
|
+
def initialize version
|
83
|
+
@version = Gem::Version.new version
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
# Instance Methods
|
88
|
+
# ========================================================================
|
89
|
+
|
90
|
+
def ruby_style_version
|
91
|
+
@ruby_style_version ||= version.to_s.gsub '.', '_'
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
def url
|
96
|
+
@url ||=
|
97
|
+
"https://github.com/ruby/ruby/archive/v#{ ruby_style_version }.tar.gz"
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
def tar_filename
|
102
|
+
@tar_filename ||= "ruby-#{ ruby_style_version }.tar.gz"
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
def tar_path
|
107
|
+
@tar_path ||= LinkStdlib.tmp_dir.join tar_filename
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
def src_path
|
112
|
+
@src_path ||= LinkStdlib.tmp_dir.join "ruby-#{ ruby_style_version }"
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
def download force: false
|
117
|
+
if force
|
118
|
+
log.info "FORCING download of Ruby #{ version } tarball..."
|
119
|
+
elsif tar_path.exist?
|
120
|
+
log.info "Ruby #{ version } tarball present."
|
121
|
+
return self
|
122
|
+
else
|
123
|
+
log.info "Downloading Ruby #{ version } tarball..."
|
124
|
+
end
|
125
|
+
|
126
|
+
response = LinkStdlib.http_get url
|
127
|
+
tar_path.open( "wb" ) { |file| file.write response.body }
|
128
|
+
|
129
|
+
self # For chaining
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
def extract force: false
|
134
|
+
if force
|
135
|
+
log.info "FORCING extraction of Ruby #{ version } source tarball..."
|
136
|
+
elsif src_path.exist?
|
137
|
+
log.info "Ruby #{ version } source present."
|
138
|
+
return self
|
139
|
+
else
|
140
|
+
log.info "Extracting #{ tar_path } -> #{ src_path }..."
|
141
|
+
end
|
142
|
+
|
143
|
+
LinkStdlib.system! \
|
144
|
+
'tar', '-x', # extract
|
145
|
+
'-f', tar_path.to_s, # file
|
146
|
+
'-C', LinkStdlib.tmp_dir.to_s # directory (chdir)
|
147
|
+
|
148
|
+
log.info "Source for Ruby #{ version } extracted to #{ src_path }."
|
149
|
+
|
150
|
+
self # For chaining
|
151
|
+
end
|
152
|
+
|
153
|
+
|
154
|
+
def ensure
|
155
|
+
if src_path.exist?
|
156
|
+
# Nothing to do, source is already in place
|
157
|
+
log.info "Source for Ruby #{ version } is present."
|
158
|
+
return
|
159
|
+
end
|
160
|
+
|
161
|
+
# Download unless the tar's already there
|
162
|
+
download
|
163
|
+
|
164
|
+
# And we must need to extract it since the src path wasn't there
|
165
|
+
extract
|
166
|
+
|
167
|
+
self # For chaining
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
def to_s
|
172
|
+
%{#<YARD::LinkStdlib::RubySource "#{ version }">}
|
173
|
+
end
|
174
|
+
|
175
|
+
def inspect; to_s; end
|
176
|
+
|
177
|
+
|
178
|
+
def <=> other
|
179
|
+
version <=> other.version
|
180
|
+
end
|
181
|
+
|
182
|
+
end # class RubySource
|
183
|
+
|
184
|
+
|
185
|
+
# /Namespace
|
186
|
+
# ========================================================================
|
187
|
+
|
188
|
+
end # module LinkStdlib
|
189
|
+
end # module YARD
|