boondoc 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +3 -1
- data/exe/boondoc +1 -1
- data/lib/boondoc/assets.rb +10 -10
- data/lib/boondoc/cli.rb +34 -32
- data/lib/boondoc/config.rb +22 -20
- data/lib/boondoc/containment.rb +3 -3
- data/lib/boondoc/context.rb +9 -2
- data/lib/boondoc/core_constants.rb +154 -14
- data/lib/boondoc/docstring_parser.rb +17 -11
- data/lib/boondoc/frontend/comments.rb +3 -3
- data/lib/boondoc/frontend/prism_parser.rb +1 -1
- data/lib/boondoc/frontend/visitor.rb +11 -11
- data/lib/boondoc/generator.rb +15 -9
- data/lib/boondoc/linker.rb +8 -8
- data/lib/boondoc/markdown.rb +6 -6
- data/lib/boondoc/model/code_object.rb +7 -7
- data/lib/boondoc/model/docstring.rb +16 -7
- data/lib/boondoc/model/registry.rb +5 -5
- data/lib/boondoc/path_map.rb +8 -8
- data/lib/boondoc/preview.rb +11 -11
- data/lib/boondoc/rake_task.rb +5 -5
- data/lib/boondoc/references.rb +1 -1
- data/lib/boondoc/renderer/base.rb +3 -3
- data/lib/boondoc/renderer/docstring.rb +33 -27
- data/lib/boondoc/renderer/index.rb +3 -3
- data/lib/boondoc/renderer/method_section.rb +6 -6
- data/lib/boondoc/renderer/namespace_page.rb +30 -20
- data/lib/boondoc/stitcher.rb +4 -4
- data/lib/boondoc/type_parser.rb +6 -6
- data/lib/boondoc/version.rb +1 -1
- data/lib/boondoc/writer.rb +12 -9
- data/lib/boondoc/yard_bridge.rb +13 -8
- data/lib/boondoc/yardopts.rb +51 -24
- data/lib/boondoc.rb +34 -34
- metadata +12 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7c13a5463fe03339e80ae333ab749e43ea5c7cb96fdbb84ea912e8244137f6e1
|
|
4
|
+
data.tar.gz: 1f5c49a3410b19c83702dd14c132c86ae6d2e2713f355a55d1785ca61d06b20f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8e66df66817ff7dad455164c0b73370af4878cd278515b1f0037e3348a8736a6480801ad08c2aa4b972cda1794ba3635f290b21fc81b0e029e3b02037155ab46
|
|
7
|
+
data.tar.gz: 1acb6c00c6d5d089d709f1303ca1dd768d597fe6a0446efa42bfa82b8d9105165c8e81a90225a7d904f659b89481fbeeec542fa06dd80197fbf15253069cdf46
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [0.2.0] - 2026-11-03
|
|
4
|
+
|
|
5
|
+
### 📦 Dependencies
|
|
6
|
+
- **prism 2.x is now allowed** (`>= 1.0, < 3`). The thor floor is now 1.2, down from 1.3; thor 1.0 and 1.1 fail to load on Ruby 3.4 and later.
|
|
7
|
+
- The README now asks for yard 0.9.39 or later with `--yard-macros`, since older releases fail on Ruby 4.0.
|
|
8
|
+
- CI runs the specs against the oldest supported versions (prism 1.0, thor 1.2, yard 0.9.39), the latest prism 1.x, prism 2.x, and without yard, using Appraisal2.
|
|
9
|
+
|
|
3
10
|
## [0.1.0] - 2026-10-25
|
|
4
11
|
|
|
5
12
|
### ✨ Features
|
data/README.md
CHANGED
|
@@ -307,9 +307,11 @@ Boondoc does not expand YARD macros and directives (`@!macro`, `@!method`,
|
|
|
307
307
|
pass `--yard-macros`:
|
|
308
308
|
|
|
309
309
|
```ruby
|
|
310
|
-
gem 'yard', group: :development
|
|
310
|
+
gem 'yard', '>= 0.9.39', group: :development
|
|
311
311
|
```
|
|
312
312
|
|
|
313
|
+
Older yard releases fail to load on Ruby 4.0, which no longer ships `ostruct`.
|
|
314
|
+
|
|
313
315
|
Prism remains the source of truth. YARD is run as a second pass and only
|
|
314
316
|
contributes the objects that directives create and the expanded docstrings of
|
|
315
317
|
comments that use a macro.
|
data/exe/boondoc
CHANGED
data/lib/boondoc/assets.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "pathname"
|
|
4
4
|
|
|
5
5
|
module Boondoc
|
|
6
6
|
# The files that are copied into the output directory next to the pages: images, video, PDFs,
|
|
@@ -53,7 +53,7 @@ module Boondoc
|
|
|
53
53
|
private
|
|
54
54
|
|
|
55
55
|
def add(map, entry)
|
|
56
|
-
from, directory = entry.split(
|
|
56
|
+
from, directory = entry.split(":", 2)
|
|
57
57
|
Dir.glob(from, base: @config.root).each do |match|
|
|
58
58
|
sources(match).each do |source, within|
|
|
59
59
|
output = directory ? output_path(directory, within) : source
|
|
@@ -73,19 +73,19 @@ module Boondoc
|
|
|
73
73
|
raise Error, "#{match} is outside the project (#{@config.root})" unless Containment.inside?(full, @config.root)
|
|
74
74
|
return [[relative(full), File.basename(full)]] if File.file?(full)
|
|
75
75
|
|
|
76
|
-
Dir.glob(
|
|
77
|
-
|
|
76
|
+
Dir.glob("**/*", base: full).select { |path| named_file?(File.join(full, path)) }
|
|
77
|
+
.map { |path| [relative(File.join(full, path)), path] }
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
def named_file?(full)
|
|
81
|
-
inside = full.delete_prefix(File.join(@config.root,
|
|
82
|
-
File.file?(full) && inside.split(
|
|
83
|
-
Containment.inside?(full, @config.root) && !full.start_with?(File.join(@config.output_dir,
|
|
81
|
+
inside = full.delete_prefix(File.join(@config.root, ""))
|
|
82
|
+
File.file?(full) && inside.split("/").none? { |part| part.start_with?(".") } &&
|
|
83
|
+
Containment.inside?(full, @config.root) && !full.start_with?(File.join(@config.output_dir, ""))
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
def output_path(directory, within)
|
|
87
87
|
path = Pathname.new(File.join(directory, within)).cleanpath.to_s
|
|
88
|
-
raise Error, "asset destination #{directory} is outside the output directory" if path.start_with?(
|
|
88
|
+
raise Error, "asset destination #{directory} is outside the output directory" if path.start_with?("..", "/")
|
|
89
89
|
|
|
90
90
|
path
|
|
91
91
|
end
|
|
@@ -96,7 +96,7 @@ module Boondoc
|
|
|
96
96
|
|
|
97
97
|
# Remembers an embedded file that is worth copying and returns where it goes.
|
|
98
98
|
def link(absolute)
|
|
99
|
-
root = File.join(@config.root,
|
|
99
|
+
root = File.join(@config.root, "")
|
|
100
100
|
return nil unless absolute.start_with?(root) && copyable?(absolute)
|
|
101
101
|
|
|
102
102
|
output = absolute.delete_prefix(root)
|
|
@@ -106,7 +106,7 @@ module Boondoc
|
|
|
106
106
|
|
|
107
107
|
def copyable?(absolute)
|
|
108
108
|
File.file?(absolute) && !Stitcher::MARKDOWN.match?(absolute) &&
|
|
109
|
-
!absolute.start_with?(File.join(@config.output_dir,
|
|
109
|
+
!absolute.start_with?(File.join(@config.output_dir, "")) && Containment.inside?(absolute, @config.root)
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
112
|
end
|
data/lib/boondoc/cli.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "thor"
|
|
4
4
|
|
|
5
5
|
module Boondoc
|
|
6
6
|
# The `boondoc` command.
|
|
@@ -14,7 +14,7 @@ module Boondoc
|
|
|
14
14
|
# @return [void]
|
|
15
15
|
def self.start_with_default(argv)
|
|
16
16
|
known = COMMANDS.include?(argv.first) || COMMAND_FLAGS.include?(argv.first)
|
|
17
|
-
start(known ? argv : [
|
|
17
|
+
start(known ? argv : ["generate", *argv])
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
# @return [Boolean] exit non-zero when a command fails
|
|
@@ -22,7 +22,7 @@ module Boondoc
|
|
|
22
22
|
true
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
desc
|
|
25
|
+
desc "generate [GLOBS]", "Write markdown documentation (default command)"
|
|
26
26
|
long_desc <<~DESC
|
|
27
27
|
Parses the Ruby files matching GLOBS (default: lib/**/*.rb) and writes one markdown
|
|
28
28
|
file per class or module, plus an index, into the output directory.
|
|
@@ -34,46 +34,48 @@ module Boondoc
|
|
|
34
34
|
The output directory must be inside the project, and not reached through a symlink.
|
|
35
35
|
Sources outside the project are skipped with a warning.
|
|
36
36
|
DESC
|
|
37
|
-
option :output, aliases:
|
|
38
|
-
option :index, type: :string, desc:
|
|
39
|
-
option :readme, type: :string, desc:
|
|
40
|
-
option :skip_readme, type: :boolean, desc:
|
|
41
|
-
option :files, type: :array, desc:
|
|
42
|
-
option :assets, type: :array, desc:
|
|
43
|
-
option :copy_linked_assets,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
option :
|
|
47
|
-
option :
|
|
48
|
-
option :
|
|
49
|
-
option :
|
|
50
|
-
option :
|
|
51
|
-
option :
|
|
52
|
-
option :
|
|
53
|
-
option :
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
37
|
+
option :output, aliases: "-o", type: :string, desc: "Output directory (default: docs)"
|
|
38
|
+
option :index, type: :string, desc: "Name of the index page (default: README.md)"
|
|
39
|
+
option :readme, type: :string, desc: "File to use as the index page (default: README.md if present)"
|
|
40
|
+
option :skip_readme, type: :boolean, desc: "Do not include a README in the index page"
|
|
41
|
+
option :files, type: :array, desc: "Extra markdown files or globs to stitch in"
|
|
42
|
+
option :assets, type: :array, desc: "Files, directories, or globs to copy into the output (FROM or FROM:DIR)"
|
|
43
|
+
option :copy_linked_assets,
|
|
44
|
+
type: :boolean,
|
|
45
|
+
desc: "Also copy the files that pages embed, such as images in the README"
|
|
46
|
+
option :exclude, type: :array, desc: "Ruby files or globs to leave out"
|
|
47
|
+
option :title, type: :string, desc: "Title for the index page when there is no README"
|
|
48
|
+
option :private, type: :boolean, desc: "Include private methods and @private objects"
|
|
49
|
+
option :protected, type: :boolean, desc: "Include protected methods"
|
|
50
|
+
option :yard_macros, type: :boolean, desc: "Expand @!macro, @!method, and @!attribute using the yard gem"
|
|
51
|
+
option :yardopts, type: :boolean, desc: "Read .yardopts (default; --no-yardopts to skip it)"
|
|
52
|
+
option :strict, type: :boolean, desc: "Exit non-zero if there are warnings"
|
|
53
|
+
option :force, type: :boolean, desc: "Overwrite files in the output directory that boondoc did not write"
|
|
54
|
+
option :allow_outside_output,
|
|
55
|
+
type: :boolean,
|
|
56
|
+
desc: "Allow an output directory outside the project (a security risk if the " \
|
|
57
|
+
"project is not trusted; for docs kept outside the repository)"
|
|
58
|
+
option :config, aliases: "-c", type: :string, desc: "Config file (default: .boondoc.yml)"
|
|
59
|
+
option :quiet, aliases: "-q", type: :boolean, desc: "Only print warnings and errors"
|
|
58
60
|
def generate(*globs)
|
|
59
61
|
Generator.new(Config.load(overrides(globs))).run
|
|
60
62
|
rescue Error => e
|
|
61
63
|
raise Thor::Error, "boondoc: #{e.message}"
|
|
62
64
|
end
|
|
63
65
|
|
|
64
|
-
desc
|
|
66
|
+
desc "serve", "Preview the generated docs in a browser with gh markdown-preview"
|
|
65
67
|
long_desc <<~DESC
|
|
66
68
|
Starts the gh markdown-preview extension of the GitHub CLI from inside the output
|
|
67
69
|
directory, so the links between pages work. Offers to install the extension when
|
|
68
70
|
it is missing. Run `boondoc` first to generate the docs.
|
|
69
71
|
DESC
|
|
70
|
-
option :output, aliases:
|
|
71
|
-
option :allow_outside_output, type: :boolean, desc:
|
|
72
|
-
option :host, type: :string, default: Preview::DEFAULT_HOST, desc:
|
|
73
|
-
option :port, aliases:
|
|
74
|
-
option :config, aliases:
|
|
72
|
+
option :output, aliases: "-o", type: :string, desc: "Directory holding the docs (default: docs)"
|
|
73
|
+
option :allow_outside_output, type: :boolean, desc: "Allow a docs directory outside the project"
|
|
74
|
+
option :host, type: :string, default: Preview::DEFAULT_HOST, desc: "Address to bind"
|
|
75
|
+
option :port, aliases: "-p", type: :numeric, desc: "Port to listen on (default: 3333)"
|
|
76
|
+
option :config, aliases: "-c", type: :string, desc: "Config file (default: .boondoc.yml)"
|
|
75
77
|
def serve
|
|
76
|
-
config = Config.load(options.slice(
|
|
78
|
+
config = Config.load(options.slice("output", "config", "allow_outside_output").transform_keys(&:to_sym))
|
|
77
79
|
Preview.new(config.output_dir, host: options[:host], port: options[:port]) do
|
|
78
80
|
yes?("The gh markdown-preview extension is not installed. Install #{Preview::EXTENSION} now? [y/N]")
|
|
79
81
|
end.start
|
|
@@ -81,7 +83,7 @@ module Boondoc
|
|
|
81
83
|
raise Thor::Error, "boondoc: #{e.message}"
|
|
82
84
|
end
|
|
83
85
|
|
|
84
|
-
desc
|
|
86
|
+
desc "version", "Print the boondoc version"
|
|
85
87
|
def version
|
|
86
88
|
puts Boondoc::VERSION
|
|
87
89
|
end
|
data/lib/boondoc/config.rb
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
3
|
+
require "yaml"
|
|
4
4
|
|
|
5
5
|
module Boondoc
|
|
6
6
|
# Options for one run, merged from defaults, `.yardopts`, `.boondoc.yml`, and the command line.
|
|
7
7
|
class Config
|
|
8
|
-
FILE =
|
|
8
|
+
FILE = ".boondoc.yml"
|
|
9
9
|
DEFAULTS = {
|
|
10
|
-
sources: [
|
|
10
|
+
sources: ["lib/**/*.rb"], exclude: [], output: "docs", index: "README.md",
|
|
11
11
|
readme: nil, files: [], assets: [], copy_linked_assets: false, title: nil,
|
|
12
12
|
private: false, protected: false, yard_macros: false,
|
|
13
13
|
strict: false, force: false, quiet: false, allow_outside_output: false, yardopts: true
|
|
@@ -23,11 +23,11 @@ module Boondoc
|
|
|
23
23
|
# A test and a description for each type name in {TYPES}.
|
|
24
24
|
CHECKS = {
|
|
25
25
|
list: [->(value) { value.is_a?(String) || (value.is_a?(Array) && value.all?(String)) },
|
|
26
|
-
|
|
27
|
-
string: [->(value) { value.is_a?(String) },
|
|
28
|
-
optional_string: [->(value) { value.nil? || value.is_a?(String) },
|
|
29
|
-
file_or_false: [->(value) { value.nil? || value == false || value.is_a?(String) },
|
|
30
|
-
boolean: [->(value) { [true, false].include?(value) },
|
|
26
|
+
"a string or a list of strings"],
|
|
27
|
+
string: [->(value) { value.is_a?(String) }, "a string"],
|
|
28
|
+
optional_string: [->(value) { value.nil? || value.is_a?(String) }, "a string"],
|
|
29
|
+
file_or_false: [->(value) { value.nil? || value == false || value.is_a?(String) }, "a file name or false"],
|
|
30
|
+
boolean: [->(value) { [true, false].include?(value) }, "true or false"]
|
|
31
31
|
}.freeze
|
|
32
32
|
|
|
33
33
|
attr_reader(*DEFAULTS.keys)
|
|
@@ -71,8 +71,9 @@ module Boondoc
|
|
|
71
71
|
settings = YAML.safe_load_file(path, symbolize_names: true) || {}
|
|
72
72
|
return settings unless settings.key?(:allow_outside_output)
|
|
73
73
|
|
|
74
|
-
raise Error,
|
|
75
|
-
|
|
74
|
+
raise Error,
|
|
75
|
+
"allow_outside_output cannot be set in a config file, because the project being " \
|
|
76
|
+
"documented is not trusted to choose it; pass --allow-outside-output on the command line"
|
|
76
77
|
end
|
|
77
78
|
private_class_method :read_file
|
|
78
79
|
|
|
@@ -84,7 +85,7 @@ module Boondoc
|
|
|
84
85
|
# @raise [Error] on unknown options, or an option of the wrong type
|
|
85
86
|
def initialize(root: Dir.pwd, from_yardopts: nil, **options)
|
|
86
87
|
unknown = options.keys - DEFAULTS.keys
|
|
87
|
-
raise Error, "unknown option#{
|
|
88
|
+
raise Error, "unknown option#{"s" if unknown.size > 1}: #{unknown.join(", ")}" if unknown.any?
|
|
88
89
|
|
|
89
90
|
@root = File.expand_path(root)
|
|
90
91
|
@yardopts_file = from_yardopts
|
|
@@ -135,7 +136,7 @@ module Boondoc
|
|
|
135
136
|
# @raise [Error] when an explicitly named README does not exist or is outside the project
|
|
136
137
|
def readme_file
|
|
137
138
|
return nil if readme == false
|
|
138
|
-
return inside_project(
|
|
139
|
+
return inside_project("README.md") if readme.nil? && File.file?(File.join(root, "README.md"))
|
|
139
140
|
return nil if readme.nil?
|
|
140
141
|
raise Error, "readme not found: #{readme}" unless File.file?(File.expand_path(readme, root))
|
|
141
142
|
|
|
@@ -159,8 +160,8 @@ module Boondoc
|
|
|
159
160
|
|
|
160
161
|
def source_split
|
|
161
162
|
@source_split ||= (expand(sources, ruby: true) - expand(exclude, ruby: true))
|
|
162
|
-
|
|
163
|
-
|
|
163
|
+
.reject { |path| excluded_by_yardopts?(path) }
|
|
164
|
+
.partition { |path| Containment.inside?(File.expand_path(path, root), root) }
|
|
164
165
|
end
|
|
165
166
|
|
|
166
167
|
def excluded_by_yardopts?(path)
|
|
@@ -170,16 +171,17 @@ module Boondoc
|
|
|
170
171
|
end
|
|
171
172
|
|
|
172
173
|
def check_output_inside(path)
|
|
173
|
-
return if path == root || path.start_with?(File.join(root,
|
|
174
|
+
return if path == root || path.start_with?(File.join(root, ""))
|
|
174
175
|
|
|
175
|
-
raise Error,
|
|
176
|
-
|
|
177
|
-
|
|
176
|
+
raise Error,
|
|
177
|
+
"output directory #{path} is outside the project (#{root}). A project must not choose where " \
|
|
178
|
+
"boondoc writes. To write there anyway, pass --allow-outside-output; that is a security " \
|
|
179
|
+
"risk if you do not trust the project, and it is how docs are kept outside the repository."
|
|
178
180
|
end
|
|
179
181
|
|
|
180
182
|
def expand(patterns, ruby: false)
|
|
181
183
|
Array(patterns).flat_map do |pattern|
|
|
182
|
-
pattern = File.join(pattern,
|
|
184
|
+
pattern = File.join(pattern, "**", "*.rb") if ruby && File.directory?(File.expand_path(pattern, root))
|
|
183
185
|
paths = Dir.glob(pattern, base: root).select { |path| File.file?(File.expand_path(path, root)) }
|
|
184
186
|
paths.map { |path| relative(path) }
|
|
185
187
|
end.uniq.sort
|
|
@@ -188,7 +190,7 @@ module Boondoc
|
|
|
188
190
|
# Paths under the root become relative to it, with `..` segments resolved.
|
|
189
191
|
def relative(path)
|
|
190
192
|
absolute = File.expand_path(path, root)
|
|
191
|
-
absolute.start_with?(File.join(root,
|
|
193
|
+
absolute.start_with?(File.join(root, "")) ? absolute.delete_prefix(File.join(root, "")) : path
|
|
192
194
|
end
|
|
193
195
|
|
|
194
196
|
# Files that are copied into the output must not come from elsewhere on the machine.
|
data/lib/boondoc/containment.rb
CHANGED
|
@@ -14,7 +14,7 @@ module Boondoc
|
|
|
14
14
|
def inside?(path, directory)
|
|
15
15
|
real = File.realpath(path)
|
|
16
16
|
base = File.realpath(directory)
|
|
17
|
-
real == base || real.start_with?(File.join(base,
|
|
17
|
+
real == base || real.start_with?(File.join(base, ""))
|
|
18
18
|
rescue SystemCallError
|
|
19
19
|
false
|
|
20
20
|
end
|
|
@@ -29,11 +29,11 @@ module Boondoc
|
|
|
29
29
|
# @return [String, nil] the first component that is a symlink, or nil when
|
|
30
30
|
# there is none or `path` is not below `directory`
|
|
31
31
|
def symlink_between(path, directory)
|
|
32
|
-
base = File.join(File.expand_path(directory),
|
|
32
|
+
base = File.join(File.expand_path(directory), "")
|
|
33
33
|
full = File.expand_path(path)
|
|
34
34
|
return nil unless full.start_with?(base)
|
|
35
35
|
|
|
36
|
-
parts = full.delete_prefix(base).split(
|
|
36
|
+
parts = full.delete_prefix(base).split("/")
|
|
37
37
|
parts.each_index.map { |count| File.join(base, *parts.first(count + 1)) }.find { |step| File.symlink?(step) }
|
|
38
38
|
end
|
|
39
39
|
end
|
data/lib/boondoc/context.rb
CHANGED
|
@@ -16,8 +16,15 @@ module Boondoc
|
|
|
16
16
|
@path_map = PathMap.new(config, registry)
|
|
17
17
|
@assets = Assets.new(config)
|
|
18
18
|
@stitcher = Stitcher.new(config, assets: assets)
|
|
19
|
-
@linker = Linker.new(
|
|
20
|
-
|
|
19
|
+
@linker = Linker.new(
|
|
20
|
+
config: config,
|
|
21
|
+
registry: registry,
|
|
22
|
+
filter: filter,
|
|
23
|
+
path_map: path_map,
|
|
24
|
+
stitcher: stitcher,
|
|
25
|
+
assets: assets,
|
|
26
|
+
reporter: reporter
|
|
27
|
+
)
|
|
21
28
|
@meths = {}
|
|
22
29
|
@aliases = {}
|
|
23
30
|
end
|
|
@@ -5,19 +5,159 @@ module Boondoc
|
|
|
5
5
|
# fixed list, because what happens to be loaded in boondoc's own process
|
|
6
6
|
# (Thor, Rake, Boondoc itself) says nothing about the project being documented.
|
|
7
7
|
CORE_CONSTANTS = %w[
|
|
8
|
-
ArgumentError
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
ArgumentError
|
|
9
|
+
Array
|
|
10
|
+
BasicObject
|
|
11
|
+
Binding
|
|
12
|
+
Class
|
|
13
|
+
ClosedQueueError
|
|
14
|
+
Comparable
|
|
15
|
+
Complex
|
|
16
|
+
ConditionVariable
|
|
17
|
+
Data
|
|
18
|
+
Dir
|
|
19
|
+
EOFError
|
|
20
|
+
Encoding
|
|
21
|
+
EncodingError
|
|
22
|
+
Enumerable
|
|
23
|
+
Enumerator
|
|
24
|
+
Errno
|
|
25
|
+
Exception
|
|
26
|
+
FalseClass
|
|
27
|
+
Fiber
|
|
28
|
+
FiberError
|
|
29
|
+
File
|
|
30
|
+
FileTest
|
|
31
|
+
Float
|
|
32
|
+
FloatDomainError
|
|
33
|
+
FrozenError
|
|
34
|
+
GC
|
|
35
|
+
Hash
|
|
36
|
+
IO
|
|
37
|
+
IOError
|
|
38
|
+
IndexError
|
|
39
|
+
Integer
|
|
40
|
+
Interrupt
|
|
41
|
+
Kernel
|
|
42
|
+
KeyError
|
|
43
|
+
LoadError
|
|
44
|
+
LocalJumpError
|
|
45
|
+
Marshal
|
|
46
|
+
MatchData
|
|
47
|
+
Math
|
|
48
|
+
Method
|
|
49
|
+
Module
|
|
50
|
+
Mutex
|
|
51
|
+
NameError
|
|
52
|
+
NilClass
|
|
53
|
+
NoMatchingPatternError
|
|
54
|
+
NoMatchingPatternKeyError
|
|
55
|
+
NoMemoryError
|
|
56
|
+
NoMethodError
|
|
57
|
+
NotImplementedError
|
|
58
|
+
Numeric
|
|
59
|
+
Object
|
|
60
|
+
ObjectSpace
|
|
61
|
+
Pathname
|
|
62
|
+
Proc
|
|
63
|
+
Process
|
|
64
|
+
Queue
|
|
65
|
+
Ractor
|
|
66
|
+
Random
|
|
67
|
+
Range
|
|
68
|
+
RangeError
|
|
69
|
+
Rational
|
|
70
|
+
Refinement
|
|
71
|
+
Regexp
|
|
72
|
+
RegexpError
|
|
73
|
+
Ruby
|
|
74
|
+
RubyVM
|
|
75
|
+
RuntimeError
|
|
76
|
+
ScriptError
|
|
77
|
+
SecurityError
|
|
78
|
+
Set
|
|
79
|
+
Signal
|
|
80
|
+
SignalException
|
|
81
|
+
SizedQueue
|
|
82
|
+
StandardError
|
|
83
|
+
StopIteration
|
|
84
|
+
String
|
|
85
|
+
Struct
|
|
86
|
+
Symbol
|
|
87
|
+
SyntaxError
|
|
88
|
+
SystemCallError
|
|
89
|
+
SystemExit
|
|
90
|
+
SystemStackError
|
|
91
|
+
Thread
|
|
92
|
+
ThreadError
|
|
93
|
+
ThreadGroup
|
|
94
|
+
Time
|
|
95
|
+
TracePoint
|
|
96
|
+
TrueClass
|
|
97
|
+
TypeError
|
|
98
|
+
UnboundMethod
|
|
99
|
+
UncaughtThrowError
|
|
100
|
+
Warning
|
|
101
|
+
ZeroDivisionError
|
|
102
|
+
Base64
|
|
103
|
+
Benchmark
|
|
104
|
+
BigDecimal
|
|
105
|
+
CGI
|
|
106
|
+
CSV
|
|
107
|
+
Coverage
|
|
108
|
+
DRb
|
|
109
|
+
Date
|
|
110
|
+
DateTime
|
|
111
|
+
Delegator
|
|
112
|
+
Digest
|
|
113
|
+
ERB
|
|
114
|
+
Etc
|
|
115
|
+
Fcntl
|
|
116
|
+
Fiddle
|
|
117
|
+
FileUtils
|
|
118
|
+
Find
|
|
119
|
+
Forwardable
|
|
120
|
+
GetoptLong
|
|
121
|
+
IPAddr
|
|
122
|
+
IPSocket
|
|
123
|
+
JSON
|
|
124
|
+
Logger
|
|
125
|
+
Monitor
|
|
126
|
+
MonitorMixin
|
|
127
|
+
Net
|
|
128
|
+
Observable
|
|
129
|
+
Open3
|
|
130
|
+
OpenSSL
|
|
131
|
+
OpenStruct
|
|
132
|
+
OptionParser
|
|
133
|
+
PP
|
|
134
|
+
PStore
|
|
135
|
+
Psych
|
|
136
|
+
Racc
|
|
137
|
+
Readline
|
|
138
|
+
Reline
|
|
139
|
+
Resolv
|
|
140
|
+
Ripper
|
|
141
|
+
SecureRandom
|
|
142
|
+
Shellwords
|
|
143
|
+
SimpleDelegator
|
|
144
|
+
Singleton
|
|
145
|
+
Socket
|
|
146
|
+
StringIO
|
|
147
|
+
StringScanner
|
|
148
|
+
Syslog
|
|
149
|
+
TCPServer
|
|
150
|
+
TCPSocket
|
|
151
|
+
Tempfile
|
|
152
|
+
Timeout
|
|
153
|
+
Tmpdir
|
|
154
|
+
TSort
|
|
155
|
+
UDPSocket
|
|
156
|
+
UNIXServer
|
|
157
|
+
UNIXSocket
|
|
158
|
+
URI
|
|
159
|
+
WeakRef
|
|
160
|
+
YAML
|
|
161
|
+
Zlib
|
|
22
162
|
].freeze
|
|
23
163
|
end
|
|
@@ -47,7 +47,7 @@ module Boondoc
|
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def continuation?(line)
|
|
50
|
-
line.strip.empty? || line.start_with?(
|
|
50
|
+
line.strip.empty? || line.start_with?(" ", "\t")
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def finish_tag
|
|
@@ -63,17 +63,17 @@ module Boondoc
|
|
|
63
63
|
|
|
64
64
|
def build(name, first, rest)
|
|
65
65
|
case name
|
|
66
|
-
when
|
|
67
|
-
when
|
|
68
|
-
when
|
|
69
|
-
when
|
|
66
|
+
when "example" then Model::Tag.new(tag_name: name, name: first, text: rest)
|
|
67
|
+
when "overload" then overload(first, rest)
|
|
68
|
+
when "option" then option(join(first, rest))
|
|
69
|
+
when "see" then see(join(first, rest))
|
|
70
70
|
when *NAMED then named(name, join(first, rest))
|
|
71
71
|
else typed(name, join(first, rest))
|
|
72
72
|
end
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
def overload(signature, rest)
|
|
76
|
-
Model::Tag.new(tag_name:
|
|
76
|
+
Model::Tag.new(tag_name: "overload", signature: signature, docstring: self.class.parse(rest))
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
# `@param name [Types] text` or `@param [Types] name text`
|
|
@@ -96,15 +96,21 @@ module Boondoc
|
|
|
96
96
|
types, text = TypeParser.extract(text.to_s)
|
|
97
97
|
key, text = text.split(/\s+/, 2)
|
|
98
98
|
default = text.to_s[/\A\((.*?)\)\s*/, 1]
|
|
99
|
-
text = text.to_s.sub(/\A\(.*?\)\s*/,
|
|
100
|
-
Model::Tag.new(
|
|
101
|
-
|
|
99
|
+
text = text.to_s.sub(/\A\(.*?\)\s*/, "") if default
|
|
100
|
+
Model::Tag.new(
|
|
101
|
+
tag_name: "option",
|
|
102
|
+
name: name,
|
|
103
|
+
types: types,
|
|
104
|
+
key: key,
|
|
105
|
+
default: default,
|
|
106
|
+
text: text.to_s.strip
|
|
107
|
+
)
|
|
102
108
|
end
|
|
103
109
|
|
|
104
110
|
# `@see reference text`
|
|
105
111
|
def see(text)
|
|
106
112
|
name, text = text.split(/\s+/, 2)
|
|
107
|
-
Model::Tag.new(tag_name:
|
|
113
|
+
Model::Tag.new(tag_name: "see", name: name, text: text.to_s.strip)
|
|
108
114
|
end
|
|
109
115
|
|
|
110
116
|
def join(first, rest)
|
|
@@ -113,7 +119,7 @@ module Boondoc
|
|
|
113
119
|
|
|
114
120
|
def dedent(lines)
|
|
115
121
|
indent = lines.reject { |line| line.strip.empty? }.map { |line| line[/\A[ \t]*/].size }.min || 0
|
|
116
|
-
lines.map { |line| line[indent..] ||
|
|
122
|
+
lines.map { |line| line[indent..] || "" }.join("\n").strip
|
|
117
123
|
end
|
|
118
124
|
end
|
|
119
125
|
end
|
|
@@ -23,7 +23,7 @@ module Boondoc
|
|
|
23
23
|
# @param line [Integer]
|
|
24
24
|
# @return [Boolean] true when the line carries a trailing `# :nodoc:`
|
|
25
25
|
def nodoc?(line)
|
|
26
|
-
@trailing[line].to_s.include?(
|
|
26
|
+
@trailing[line].to_s.include?(":nodoc:")
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
# @return [Array<Integer>] last lines of comment blocks that contain YARD directives
|
|
@@ -58,9 +58,9 @@ module Boondoc
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def clean(lines)
|
|
61
|
-
lines = lines.grep_v(IGNORED).map { |line| line.delete_prefix(
|
|
61
|
+
lines = lines.grep_v(IGNORED).map { |line| line.delete_prefix("#").rstrip }
|
|
62
62
|
indent = lines.reject(&:empty?).map { |line| line[/\A */].size }.min || 0
|
|
63
|
-
lines.map { |line| line[indent..] ||
|
|
63
|
+
lines.map { |line| line[indent..] || "" }.join("\n")
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
66
|
end
|
|
@@ -21,7 +21,7 @@ module Boondoc
|
|
|
21
21
|
# @param source [String] Ruby source
|
|
22
22
|
# @param label [String] file name to record on objects
|
|
23
23
|
# @return [void]
|
|
24
|
-
def parse(source, label =
|
|
24
|
+
def parse(source, label = "(source)")
|
|
25
25
|
result = ::Prism.parse(source)
|
|
26
26
|
return syntax_error(label, result) if result.failure?
|
|
27
27
|
|