yard-markdown 0.6.0 → 0.7.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/.yard-lint.yml +317 -0
- data/AGENTS.md +54 -0
- data/CHANGELOG.md +17 -0
- data/README.md +8 -0
- data/Rakefile +41 -0
- data/config/mutant.yml +25 -0
- data/lib/yard/markdown/anchor_component_helper.rb +20 -0
- data/lib/yard/markdown/aref_helper.rb +31 -0
- data/lib/yard/markdown/collection_rendering_helper.rb +96 -0
- data/lib/yard/markdown/documentation_helper.rb +30 -0
- data/lib/yard/markdown/heading_helper.rb +52 -0
- data/lib/yard/markdown/link_normalization_helper.rb +144 -0
- data/lib/yard/markdown/method_presentation_helper.rb +49 -0
- data/lib/yard/markdown/object_listing_helper.rb +87 -0
- data/lib/yard/markdown/relationship_section_helper.rb +38 -0
- data/lib/yard/markdown/section_assembly_helper.rb +46 -0
- data/lib/yard/markdown/tag_formatting_helper.rb +75 -0
- data/lib/yard-markdown.rb +11 -0
- data/sig/yard/markdown.rbs +346 -4
- data/templates/default/fulldoc/markdown/setup.rb +14 -69
- data/templates/default/module/markdown/setup.rb +54 -413
- metadata +17 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 41e14595e84affb837da2c36afb9a40f0e7ea866472fa32e5aefabc7c32c2ec8
|
|
4
|
+
data.tar.gz: 605f1ad9c9496ebaf48afc7245ab25db98b5e22aed88c7c718bb3968f78b3b5e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0887584b2fe63298271fad1483237eb303d215068a6da79aee7cb59c463a6c2838a6a72171676e7876f7a7d8c9003c0e23eb0fcb9dbfd88e329f028c5907bdef'
|
|
7
|
+
data.tar.gz: 9d50e908447b65b564315c996af01a43e35d360f2bafd600d34197ed20fc0cf8fde1b506850eb2fd476ee65d33c44ff10de8658abcd51037011060d4e69ec59f
|
data/.yard-lint.yml
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# YARD-Lint Configuration (Strict Mode)
|
|
2
|
+
# See https://github.com/mensfeld/yard-lint for documentation
|
|
3
|
+
#
|
|
4
|
+
# This is a strict configuration suitable for new projects with high documentation standards.
|
|
5
|
+
# All validators are set to 'error' severity (no warnings or conventions).
|
|
6
|
+
# Minimum coverage is set to 100%.
|
|
7
|
+
|
|
8
|
+
# Global settings for all validators
|
|
9
|
+
AllValidators:
|
|
10
|
+
# YARD command-line options (applied to all validators by default)
|
|
11
|
+
YardOptions:
|
|
12
|
+
- --private
|
|
13
|
+
- --protected
|
|
14
|
+
|
|
15
|
+
# Global file exclusion patterns
|
|
16
|
+
Exclude:
|
|
17
|
+
- '\.git'
|
|
18
|
+
- "vendor/**/*"
|
|
19
|
+
- "node_modules/**/*"
|
|
20
|
+
- "spec/**/*"
|
|
21
|
+
- "test/**/*"
|
|
22
|
+
- "tmp/**/*"
|
|
23
|
+
- "example_rdoc.rb"
|
|
24
|
+
- "example_yard.rb"
|
|
25
|
+
|
|
26
|
+
# Exit code behavior (error, warning, convention, never)
|
|
27
|
+
FailOnSeverity: error
|
|
28
|
+
|
|
29
|
+
# Minimum documentation coverage percentage (0-100)
|
|
30
|
+
# Fails if coverage is below this threshold
|
|
31
|
+
MinCoverage: 100.0
|
|
32
|
+
|
|
33
|
+
# Diff mode settings
|
|
34
|
+
DiffMode:
|
|
35
|
+
# Default base ref for --diff (auto-detects main/master if not specified)
|
|
36
|
+
DefaultBaseRef: ~
|
|
37
|
+
|
|
38
|
+
# Documentation validators
|
|
39
|
+
Documentation/UndocumentedObjects:
|
|
40
|
+
Description: "Checks for classes, modules, and methods without documentation."
|
|
41
|
+
Enabled: true
|
|
42
|
+
Severity: error
|
|
43
|
+
ExcludedMethods:
|
|
44
|
+
- "initialize/0" # Exclude parameter-less initialize
|
|
45
|
+
- "/^_/" # Exclude private methods (by convention)
|
|
46
|
+
|
|
47
|
+
Documentation/UndocumentedMethodArguments:
|
|
48
|
+
Description: "Checks for method parameters without @param tags."
|
|
49
|
+
Enabled: true
|
|
50
|
+
Severity: error
|
|
51
|
+
|
|
52
|
+
Documentation/UndocumentedBooleanMethods:
|
|
53
|
+
Description: "Checks that question mark methods document their boolean return."
|
|
54
|
+
Enabled: true
|
|
55
|
+
Severity: error
|
|
56
|
+
|
|
57
|
+
Documentation/UndocumentedOptions:
|
|
58
|
+
Description: "Detects methods with options hash parameters but no @option tags."
|
|
59
|
+
Enabled: true
|
|
60
|
+
Severity: error
|
|
61
|
+
|
|
62
|
+
Documentation/MissingReturn:
|
|
63
|
+
Description: "Requires @return tags on all methods (opt-in for strict documentation)."
|
|
64
|
+
Enabled: true # Enabled in strict mode
|
|
65
|
+
Severity: error
|
|
66
|
+
ExcludedMethods:
|
|
67
|
+
- "initialize" # Exclude all initialize methods
|
|
68
|
+
# - '/^_/' # Uncomment to exclude private methods (by convention)
|
|
69
|
+
|
|
70
|
+
Documentation/MarkdownSyntax:
|
|
71
|
+
Description: "Detects common markdown syntax errors in documentation."
|
|
72
|
+
Enabled: true
|
|
73
|
+
Severity: error
|
|
74
|
+
|
|
75
|
+
Documentation/EmptyCommentLine:
|
|
76
|
+
Description: "Detects empty comment lines at the start or end of documentation blocks."
|
|
77
|
+
Enabled: true
|
|
78
|
+
Severity: error
|
|
79
|
+
EnabledPatterns:
|
|
80
|
+
Leading: true
|
|
81
|
+
Trailing: true
|
|
82
|
+
|
|
83
|
+
Documentation/BlankLineBeforeDefinition:
|
|
84
|
+
Description: "Detects blank lines between YARD documentation and method definition."
|
|
85
|
+
Enabled: true
|
|
86
|
+
Severity: error
|
|
87
|
+
OrphanedSeverity: error
|
|
88
|
+
EnabledPatterns:
|
|
89
|
+
SingleBlankLine: true
|
|
90
|
+
OrphanedDocs: true
|
|
91
|
+
|
|
92
|
+
# Tags validators
|
|
93
|
+
Tags/Order:
|
|
94
|
+
Description: "Enforces consistent ordering of YARD tags."
|
|
95
|
+
Enabled: true
|
|
96
|
+
Severity: error
|
|
97
|
+
EnforcedOrder:
|
|
98
|
+
- param
|
|
99
|
+
- option
|
|
100
|
+
- yield
|
|
101
|
+
- yieldparam
|
|
102
|
+
- yieldreturn
|
|
103
|
+
- return
|
|
104
|
+
- raise
|
|
105
|
+
- see
|
|
106
|
+
- example
|
|
107
|
+
- note
|
|
108
|
+
- todo
|
|
109
|
+
|
|
110
|
+
Tags/InvalidTypes:
|
|
111
|
+
Description: "Validates type definitions in @param, @return, @option tags."
|
|
112
|
+
Enabled: true
|
|
113
|
+
Severity: error
|
|
114
|
+
ValidatedTags:
|
|
115
|
+
- param
|
|
116
|
+
- option
|
|
117
|
+
- return
|
|
118
|
+
|
|
119
|
+
Tags/TypeSyntax:
|
|
120
|
+
Description: "Validates YARD type syntax using YARD parser."
|
|
121
|
+
Enabled: true
|
|
122
|
+
Severity: error
|
|
123
|
+
ValidatedTags:
|
|
124
|
+
- param
|
|
125
|
+
- option
|
|
126
|
+
- return
|
|
127
|
+
- yieldreturn
|
|
128
|
+
|
|
129
|
+
Tags/MeaninglessTag:
|
|
130
|
+
Description: "Detects @param/@option tags on classes, modules, or constants."
|
|
131
|
+
Enabled: true
|
|
132
|
+
Severity: error
|
|
133
|
+
CheckedTags:
|
|
134
|
+
- param
|
|
135
|
+
- option
|
|
136
|
+
InvalidObjectTypes:
|
|
137
|
+
- class
|
|
138
|
+
- module
|
|
139
|
+
- constant
|
|
140
|
+
|
|
141
|
+
Tags/CollectionType:
|
|
142
|
+
Description: "Validates Hash collection syntax consistency."
|
|
143
|
+
Enabled: true
|
|
144
|
+
Severity: error
|
|
145
|
+
EnforcedStyle: long # 'long' for Hash{K => V} (YARD standard), 'short' for {K => V}
|
|
146
|
+
ValidatedTags:
|
|
147
|
+
- param
|
|
148
|
+
- option
|
|
149
|
+
- return
|
|
150
|
+
- yieldreturn
|
|
151
|
+
|
|
152
|
+
Tags/TagTypePosition:
|
|
153
|
+
Description: "Validates type annotation position in tags."
|
|
154
|
+
Enabled: true
|
|
155
|
+
Severity: error
|
|
156
|
+
CheckedTags:
|
|
157
|
+
- param
|
|
158
|
+
- option
|
|
159
|
+
# EnforcedStyle: 'type_after_name' (YARD standard: @param name [Type])
|
|
160
|
+
# or 'type_first' (@param [Type] name)
|
|
161
|
+
EnforcedStyle: type_after_name
|
|
162
|
+
|
|
163
|
+
Tags/ApiTags:
|
|
164
|
+
Description: "Enforces @api tags on public objects."
|
|
165
|
+
Enabled: false # Opt-in validator
|
|
166
|
+
Severity: error
|
|
167
|
+
AllowedApis:
|
|
168
|
+
- public
|
|
169
|
+
- private
|
|
170
|
+
- internal
|
|
171
|
+
|
|
172
|
+
Tags/OptionTags:
|
|
173
|
+
Description: "Requires @option tags for methods with options parameters."
|
|
174
|
+
Enabled: true
|
|
175
|
+
Severity: error
|
|
176
|
+
|
|
177
|
+
Tags/ExampleSyntax:
|
|
178
|
+
Description: "Validates Ruby syntax in @example tags."
|
|
179
|
+
Enabled: true
|
|
180
|
+
Severity: error
|
|
181
|
+
|
|
182
|
+
Tags/ExampleStyle:
|
|
183
|
+
Description: "Validates code style in @example tags using RuboCop/StandardRB."
|
|
184
|
+
Enabled: false # Opt-in validator (requires RuboCop or StandardRB)
|
|
185
|
+
Severity: convention
|
|
186
|
+
# Linter: auto # Uncomment to explicitly configure: 'auto', 'rubocop', 'standard', 'none'
|
|
187
|
+
# SkipPatterns: # Uncomment to skip examples matching patterns
|
|
188
|
+
# - '/skip-lint/i'
|
|
189
|
+
# - '/bad code/i'
|
|
190
|
+
|
|
191
|
+
Tags/RedundantParamDescription:
|
|
192
|
+
Description: "Detects meaningless parameter descriptions that add no value."
|
|
193
|
+
Enabled: true
|
|
194
|
+
Severity: error
|
|
195
|
+
CheckedTags:
|
|
196
|
+
- param
|
|
197
|
+
- option
|
|
198
|
+
Articles:
|
|
199
|
+
- The
|
|
200
|
+
- the
|
|
201
|
+
- A
|
|
202
|
+
- a
|
|
203
|
+
- An
|
|
204
|
+
- an
|
|
205
|
+
MaxRedundantWords: 6
|
|
206
|
+
GenericTerms:
|
|
207
|
+
- object
|
|
208
|
+
- instance
|
|
209
|
+
- value
|
|
210
|
+
- data
|
|
211
|
+
- item
|
|
212
|
+
- element
|
|
213
|
+
EnabledPatterns:
|
|
214
|
+
ArticleParam: true
|
|
215
|
+
PossessiveParam: true
|
|
216
|
+
TypeRestatement: true
|
|
217
|
+
ParamToVerb: true
|
|
218
|
+
IdPattern: true
|
|
219
|
+
DirectionalDate: true
|
|
220
|
+
TypeGeneric: true
|
|
221
|
+
|
|
222
|
+
Tags/InformalNotation:
|
|
223
|
+
Description: 'Detects informal tag notation patterns like "Note:" instead of @note.'
|
|
224
|
+
Enabled: true
|
|
225
|
+
Severity: error
|
|
226
|
+
CaseSensitive: false
|
|
227
|
+
RequireStartOfLine: true
|
|
228
|
+
Patterns:
|
|
229
|
+
Note: "@note"
|
|
230
|
+
Todo: "@todo"
|
|
231
|
+
TODO: "@todo"
|
|
232
|
+
FIXME: "@todo"
|
|
233
|
+
See: "@see"
|
|
234
|
+
See also: "@see"
|
|
235
|
+
Warning: "@deprecated"
|
|
236
|
+
Deprecated: "@deprecated"
|
|
237
|
+
Author: "@author"
|
|
238
|
+
Version: "@version"
|
|
239
|
+
Since: "@since"
|
|
240
|
+
Returns: "@return"
|
|
241
|
+
Raises: "@raise"
|
|
242
|
+
Example: "@example"
|
|
243
|
+
|
|
244
|
+
Tags/NonAsciiType:
|
|
245
|
+
Description: "Detects non-ASCII characters in type annotations."
|
|
246
|
+
Enabled: true
|
|
247
|
+
Severity: error
|
|
248
|
+
ValidatedTags:
|
|
249
|
+
- param
|
|
250
|
+
- option
|
|
251
|
+
- return
|
|
252
|
+
- yieldreturn
|
|
253
|
+
- yieldparam
|
|
254
|
+
|
|
255
|
+
Tags/TagGroupSeparator:
|
|
256
|
+
Description: "Enforces blank line separators between different YARD tag groups."
|
|
257
|
+
Enabled: false # Opt-in validator
|
|
258
|
+
Severity: error
|
|
259
|
+
TagGroups:
|
|
260
|
+
param: [param, option]
|
|
261
|
+
return: [return]
|
|
262
|
+
error: [raise, throws]
|
|
263
|
+
example: [example]
|
|
264
|
+
meta: [see, note, todo, deprecated, since, version, api]
|
|
265
|
+
yield: [yield, yieldparam, yieldreturn]
|
|
266
|
+
RequireAfterDescription: false
|
|
267
|
+
|
|
268
|
+
Tags/ForbiddenTags:
|
|
269
|
+
Description: "Detects forbidden tag and type combinations."
|
|
270
|
+
Enabled: false # Opt-in validator
|
|
271
|
+
Severity: error
|
|
272
|
+
ForbiddenPatterns: []
|
|
273
|
+
# Example patterns:
|
|
274
|
+
# - Tag: return
|
|
275
|
+
# Types:
|
|
276
|
+
# - void
|
|
277
|
+
# - Tag: param
|
|
278
|
+
# Types:
|
|
279
|
+
# - Object
|
|
280
|
+
# - Tag: api # Forbids @api tag entirely (no Types = any occurrence)
|
|
281
|
+
|
|
282
|
+
# Warnings validators - catches YARD parser errors
|
|
283
|
+
Warnings/UnknownTag:
|
|
284
|
+
Description: "Detects unknown YARD tags."
|
|
285
|
+
Enabled: true
|
|
286
|
+
Severity: error
|
|
287
|
+
|
|
288
|
+
Warnings/UnknownDirective:
|
|
289
|
+
Description: "Detects unknown YARD directives."
|
|
290
|
+
Enabled: true
|
|
291
|
+
Severity: error
|
|
292
|
+
|
|
293
|
+
Warnings/InvalidTagFormat:
|
|
294
|
+
Description: "Detects malformed tag syntax."
|
|
295
|
+
Enabled: true
|
|
296
|
+
Severity: error
|
|
297
|
+
|
|
298
|
+
Warnings/InvalidDirectiveFormat:
|
|
299
|
+
Description: "Detects malformed directive syntax."
|
|
300
|
+
Enabled: true
|
|
301
|
+
Severity: error
|
|
302
|
+
|
|
303
|
+
Warnings/DuplicatedParameterName:
|
|
304
|
+
Description: "Detects duplicate @param tags."
|
|
305
|
+
Enabled: true
|
|
306
|
+
Severity: error
|
|
307
|
+
|
|
308
|
+
Warnings/UnknownParameterName:
|
|
309
|
+
Description: "Detects @param tags for non-existent parameters."
|
|
310
|
+
Enabled: true
|
|
311
|
+
Severity: error
|
|
312
|
+
|
|
313
|
+
# Semantic validators
|
|
314
|
+
Semantic/AbstractMethods:
|
|
315
|
+
Description: "Ensures @abstract methods do not have real implementations."
|
|
316
|
+
Enabled: true
|
|
317
|
+
Severity: error
|
data/AGENTS.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
You are working in a Ruby project that uses mutation testing.
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Achieve 100% mutation coverage. Verify with:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
bundle exec mutant run
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
When iterating, prefer `--fail-fast` so you address one surviving
|
|
12
|
+
mutant at a time:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
bundle exec mutant run --fail-fast
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## When you find an alive mutation
|
|
19
|
+
|
|
20
|
+
Decide which bucket it falls into:
|
|
21
|
+
|
|
22
|
+
- **A) The code does too much** for what the tests ask for. The
|
|
23
|
+
surviving mutation reveals behavior that no test requires. The
|
|
24
|
+
fix is to simplify the implementation.
|
|
25
|
+
- **B) A test is missing.** The behavior is intentional but no test
|
|
26
|
+
observes it. The fix is to add a test.
|
|
27
|
+
|
|
28
|
+
Decide between A) and B) before changing anything. If unsure, ask
|
|
29
|
+
the user.
|
|
30
|
+
|
|
31
|
+
## Constraints
|
|
32
|
+
|
|
33
|
+
- Line coverage must stay at 100%. Verify with:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
SIMPLECOV=1 bundle exec rake test
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- You may not skip mutants by configuring mutant to ignore them.
|
|
40
|
+
No `expressions:` filters, no `coverage_criteria:` tweaks.
|
|
41
|
+
- You may not use `send` or `__send__` to invoke private methods
|
|
42
|
+
in tests just to satisfy mutant.
|
|
43
|
+
- You may not stub or mock the system under test (`Age`).
|
|
44
|
+
|
|
45
|
+
## Done
|
|
46
|
+
|
|
47
|
+
You are done when both of these are green and don't return any offenses:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
SIMPLECOV=1 bundle exec rake test
|
|
51
|
+
bundle exec mutant run
|
|
52
|
+
bundle exec rake markdown:validate_real_world
|
|
53
|
+
yard-lint lib/
|
|
54
|
+
```
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
All notable changes to this project will be documented in this file.
|
|
3
|
+
|
|
4
|
+
This format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
5
|
+
|
|
6
|
+
## Unreleased
|
|
7
|
+
|
|
8
|
+
## 0.7.0
|
|
9
|
+
## Added
|
|
10
|
+
- Adding yard-lint and all method documentation
|
|
11
|
+
- Generating rbs signature based on yard tags
|
|
12
|
+
- Adding mutant testing into a project
|
|
13
|
+
|
|
14
|
+
## Changed
|
|
15
|
+
- Refactoring and simplification of teamplate, mostly driven by mutantion testing
|
|
16
|
+
- Improve documentation for entire project
|
|
17
|
+
|
data/README.md
CHANGED
|
@@ -63,6 +63,12 @@ Validate generated markdown in sample docs:
|
|
|
63
63
|
bundle exec rake markdown:validate_examples
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
+
Regenerate the checked-in RBS types derived from YARD docs:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
bundle exec rake types:generate
|
|
70
|
+
```
|
|
71
|
+
|
|
66
72
|
There is also a real-world validation harness for repositories with substantial YARD documentation (`rspec-core`, `sidekiq`):
|
|
67
73
|
|
|
68
74
|
```bash
|
|
@@ -73,4 +79,6 @@ This task validates generated markdown against CommonMark + GFM rendering, and r
|
|
|
73
79
|
|
|
74
80
|
GitHub Actions CI now runs this task on every push/PR, so `sidekiq` and other real-world fixture gems are verified continuously.
|
|
75
81
|
|
|
82
|
+
CI also regenerates `sig/yard/markdown.rbs` with `sord` and fails if the checked-in RBS file is out of date.
|
|
83
|
+
|
|
76
84
|
For reproducible checks, the task clones pinned tags (`rspec-core` `v3.13.2`, `sidekiq` `v7.3.10`) into `tmp/real-world/repos` before generating output.
|
data/Rakefile
CHANGED
|
@@ -17,6 +17,8 @@ end
|
|
|
17
17
|
|
|
18
18
|
task default: %i[test stree:write]
|
|
19
19
|
|
|
20
|
+
TYPES_OUTPUT_PATH = "sig/yard/markdown.rbs"
|
|
21
|
+
|
|
20
22
|
def shell_escape(path)
|
|
21
23
|
Shellwords.escape(path)
|
|
22
24
|
end
|
|
@@ -84,6 +86,33 @@ def checkout_repo(url, destination, ref: nil)
|
|
|
84
86
|
run_command_with_analysis(command, label: "git_clone_#{destination}")
|
|
85
87
|
end
|
|
86
88
|
|
|
89
|
+
def generate_types(output_path = TYPES_OUTPUT_PATH)
|
|
90
|
+
FileUtils.mkdir_p(File.dirname(output_path))
|
|
91
|
+
|
|
92
|
+
command = [
|
|
93
|
+
"sord gen",
|
|
94
|
+
"--rbs",
|
|
95
|
+
"--no-sord-comments",
|
|
96
|
+
"--replace-unresolved-with-untyped",
|
|
97
|
+
"--replace-errors-with-untyped",
|
|
98
|
+
shell_escape(output_path)
|
|
99
|
+
].join(" ")
|
|
100
|
+
|
|
101
|
+
run_command_with_analysis(command, label: "sord_generate")
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def ensure_clean_generated_file(path)
|
|
105
|
+
command = "git status --short -- #{shell_escape(path)}"
|
|
106
|
+
stdout, stderr, status = Open3.capture3(command)
|
|
107
|
+
combined_output = [stdout, stderr].reject(&:empty?).join("\n")
|
|
108
|
+
|
|
109
|
+
raise "Unable to verify generated types for #{path}" unless status.success?
|
|
110
|
+
return if combined_output.strip.empty?
|
|
111
|
+
|
|
112
|
+
puts combined_output
|
|
113
|
+
raise "#{path} is out of date. Run `bundle exec rake types:generate` and commit the updated file."
|
|
114
|
+
end
|
|
115
|
+
|
|
87
116
|
|
|
88
117
|
namespace :examples do
|
|
89
118
|
desc "Generate basic example documentation using yard-markdown plugin"
|
|
@@ -153,3 +182,15 @@ namespace :markdown do
|
|
|
153
182
|
end
|
|
154
183
|
end
|
|
155
184
|
end
|
|
185
|
+
|
|
186
|
+
namespace :types do
|
|
187
|
+
desc "Generate checked-in RBS types from YARD documentation"
|
|
188
|
+
task :generate do
|
|
189
|
+
generate_types
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
desc "Verify checked-in RBS types are up to date"
|
|
193
|
+
task check: :generate do
|
|
194
|
+
ensure_clean_generated_file(TYPES_OUTPUT_PATH)
|
|
195
|
+
end
|
|
196
|
+
end
|
data/config/mutant.yml
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
usage: opensource
|
|
2
|
+
|
|
3
|
+
integration:
|
|
4
|
+
name: minitest
|
|
5
|
+
|
|
6
|
+
includes:
|
|
7
|
+
- lib
|
|
8
|
+
- test
|
|
9
|
+
|
|
10
|
+
requires:
|
|
11
|
+
- ./test/support/mutant_setup.rb
|
|
12
|
+
|
|
13
|
+
matcher:
|
|
14
|
+
subjects:
|
|
15
|
+
- YARD::Markdown::AnchorComponentHelper#
|
|
16
|
+
- YARD::Markdown::ArefHelper#
|
|
17
|
+
- YARD::Markdown::CollectionRenderingHelper#
|
|
18
|
+
- YARD::Markdown::DocumentationHelper#
|
|
19
|
+
- YARD::Markdown::HeadingHelper#
|
|
20
|
+
- YARD::Markdown::LinkNormalizationHelper#
|
|
21
|
+
- YARD::Markdown::MethodPresentationHelper#
|
|
22
|
+
- YARD::Markdown::ObjectListingHelper#
|
|
23
|
+
- YARD::Markdown::RelationshipSectionHelper#
|
|
24
|
+
- YARD::Markdown::SectionAssemblyHelper#
|
|
25
|
+
- YARD::Markdown::TagFormattingHelper#
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Namespace for YARD extensions used by this gem.
|
|
4
|
+
module YARD
|
|
5
|
+
# Shared helpers for rendering YARD objects as Markdown.
|
|
6
|
+
module Markdown
|
|
7
|
+
# Builds anchor-safe identifier fragments from arbitrary values.
|
|
8
|
+
module AnchorComponentHelper
|
|
9
|
+
# Encodes a value so it can be embedded safely in an HTML anchor id.
|
|
10
|
+
#
|
|
11
|
+
# @param value [Object] Raw anchor fragment to encode.
|
|
12
|
+
# @return [String] Anchor-safe identifier fragment.
|
|
13
|
+
def anchor_component(value)
|
|
14
|
+
value.to_s.each_char.map do |char|
|
|
15
|
+
char.match?(/[A-Za-z0-9_-]/) ? char : format('-%X', char.ord)
|
|
16
|
+
end.join
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module YARD
|
|
4
|
+
module Markdown
|
|
5
|
+
# Computes anchor ids that match the generated Markdown headings.
|
|
6
|
+
module ArefHelper
|
|
7
|
+
include AnchorComponentHelper
|
|
8
|
+
|
|
9
|
+
# Returns the primary anchor id for a documented object.
|
|
10
|
+
#
|
|
11
|
+
# @param object [YARD::CodeObjects::Base] Object being rendered.
|
|
12
|
+
# @return [String] Anchor id for the object's heading.
|
|
13
|
+
def aref(object)
|
|
14
|
+
type = object.type
|
|
15
|
+
|
|
16
|
+
return "class-#{object.path.gsub('::', '-')}" if type == :class
|
|
17
|
+
return "module-#{object.path.gsub('::', '-')}" if type == :module
|
|
18
|
+
return "constant-#{object.name}" if type == :constant
|
|
19
|
+
return "classvariable-#{anchor_component(object.name)}" if type == :classvariable
|
|
20
|
+
|
|
21
|
+
scope = object.scope == :class ? 'c' : 'i'
|
|
22
|
+
|
|
23
|
+
if !object.attr_info.nil?
|
|
24
|
+
"attribute-#{scope}-#{object.name}"
|
|
25
|
+
else
|
|
26
|
+
"method-#{scope}-#{anchor_component(object.name)}"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module YARD
|
|
4
|
+
module Markdown
|
|
5
|
+
# Renders grouped Markdown sections for constants, attributes, and methods.
|
|
6
|
+
module CollectionRenderingHelper
|
|
7
|
+
# Renders the constants section for an object page.
|
|
8
|
+
#
|
|
9
|
+
# @param constants [Array<YARD::CodeObjects::Base>] Constant objects collected for the current page.
|
|
10
|
+
# @param group_order [Array<String>, nil] Preferred ordering for group headings.
|
|
11
|
+
# @return [String] Markdown for the constants section.
|
|
12
|
+
def render_constants(constants, group_order)
|
|
13
|
+
lines = ['## Constants']
|
|
14
|
+
grouped_constants = grouped_items(constants.sort_by { |item| item.name }, group_order)
|
|
15
|
+
uses_groups = grouped_constants.any? { |name, _items| !name.nil? }
|
|
16
|
+
|
|
17
|
+
grouped_constants.each do |group_name, items|
|
|
18
|
+
if uses_groups
|
|
19
|
+
lines << "### #{group_name || 'General'}"
|
|
20
|
+
item_heading = '####'
|
|
21
|
+
else
|
|
22
|
+
item_heading = '###'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
lines << items.map { |item|
|
|
26
|
+
item_lines = [heading_with_anchors("#{item_heading} `#{item.name}`", item)]
|
|
27
|
+
append_lines(item_lines, documented_text(item), separated: false)
|
|
28
|
+
append_lines(item_lines, render_tags(item), separated: false)
|
|
29
|
+
item_lines.join("\n")
|
|
30
|
+
}.join("\n\n")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
lines.join("\n")
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Renders the attributes section for an object page.
|
|
37
|
+
#
|
|
38
|
+
# @param attrs [Array<YARD::CodeObjects::MethodObject>] Attributes to render.
|
|
39
|
+
# @param group_order [Array<String>, nil] Preferred ordering for group headings.
|
|
40
|
+
# @return [String] Markdown for the attributes section.
|
|
41
|
+
def render_attributes(attrs, group_order)
|
|
42
|
+
lines = ['## Attributes']
|
|
43
|
+
grouped_attrs = grouped_items(attrs, group_order)
|
|
44
|
+
uses_groups = grouped_attrs.any? { |name, _items| !name.nil? }
|
|
45
|
+
|
|
46
|
+
grouped_attrs.each do |group_name, items|
|
|
47
|
+
if uses_groups
|
|
48
|
+
lines << "### #{group_name || 'General'}"
|
|
49
|
+
item_heading = '####'
|
|
50
|
+
else
|
|
51
|
+
item_heading = '###'
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
lines << items.map { |item|
|
|
55
|
+
item_lines = [heading_with_anchors("#{item_heading} `#{item.name}` [#{attribute_access(item)}]", item)]
|
|
56
|
+
append_lines(item_lines, documented_text(item), separated: false)
|
|
57
|
+
append_lines(item_lines, render_tags(item), separated: false)
|
|
58
|
+
item_lines.join("\n")
|
|
59
|
+
}.join("\n\n")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
lines.join("\n")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Renders a method section for an object page.
|
|
66
|
+
#
|
|
67
|
+
# @param section_title [String] Section title to render.
|
|
68
|
+
# @param methods [Array<YARD::CodeObjects::MethodObject>] Method objects collected for the current section.
|
|
69
|
+
# @param group_order [Array<String>, nil] Preferred ordering for group headings.
|
|
70
|
+
# @return [String] Markdown for the method section.
|
|
71
|
+
def render_methods(section_title, methods, group_order)
|
|
72
|
+
lines = ["## #{section_title}"]
|
|
73
|
+
grouped_methods = grouped_items(methods, group_order)
|
|
74
|
+
uses_groups = grouped_methods.any? { |name, _items| !name.nil? }
|
|
75
|
+
|
|
76
|
+
grouped_methods.each do |group_name, items|
|
|
77
|
+
if uses_groups
|
|
78
|
+
lines << "### #{group_name || 'General'}"
|
|
79
|
+
item_heading = '####'
|
|
80
|
+
else
|
|
81
|
+
item_heading = '###'
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
lines << items.map { |item|
|
|
85
|
+
item_lines = [heading_with_anchors("#{item_heading} `#{formatted_method_heading(item)}`", item)]
|
|
86
|
+
append_lines(item_lines, documented_text(item), separated: false)
|
|
87
|
+
append_lines(item_lines, render_tags(item), separated: false)
|
|
88
|
+
item_lines.join("\n")
|
|
89
|
+
}.join("\n\n")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
lines.join("\n")
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rdoc'
|
|
4
|
+
|
|
5
|
+
module YARD
|
|
6
|
+
module Markdown
|
|
7
|
+
# Converts YARD docstrings into Markdown-friendly text.
|
|
8
|
+
module DocumentationHelper
|
|
9
|
+
# Returns the rendered documentation text for an object.
|
|
10
|
+
#
|
|
11
|
+
# @param object [YARD::CodeObjects::Base] Object whose docstring is being rendered.
|
|
12
|
+
# @return [String] Converted documentation text or a fallback message.
|
|
13
|
+
def documented_text(object)
|
|
14
|
+
text = rdoc_to_md(object.docstring)
|
|
15
|
+
return text unless text.empty?
|
|
16
|
+
return '' unless object.tags.empty?
|
|
17
|
+
|
|
18
|
+
'Not documented.'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Converts an RDoc-formatted docstring to Markdown.
|
|
22
|
+
#
|
|
23
|
+
# @param docstring [Object] Raw docstring content.
|
|
24
|
+
# @return [String] Markdown-rendered docstring content.
|
|
25
|
+
def rdoc_to_md(docstring)
|
|
26
|
+
RDoc::Markup::ToMarkdown.new.convert(docstring).rstrip
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|