docscribe 1.0.0 → 1.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/README.md +692 -180
- data/exe/docscribe +2 -74
- data/lib/docscribe/cli/config_builder.rb +62 -0
- data/lib/docscribe/cli/init.rb +58 -0
- data/lib/docscribe/cli/options.rb +204 -0
- data/lib/docscribe/cli/run.rb +415 -0
- data/lib/docscribe/cli.rb +31 -0
- data/lib/docscribe/config/defaults.rb +71 -0
- data/lib/docscribe/config/emit.rb +126 -0
- data/lib/docscribe/config/filtering.rb +160 -0
- data/lib/docscribe/config/loader.rb +59 -0
- data/lib/docscribe/config/rbs.rb +51 -0
- data/lib/docscribe/config/sorbet.rb +87 -0
- data/lib/docscribe/config/sorting.rb +23 -0
- data/lib/docscribe/config/template.rb +176 -0
- data/lib/docscribe/config/utils.rb +102 -0
- data/lib/docscribe/config.rb +20 -230
- data/lib/docscribe/infer/ast_walk.rb +28 -0
- data/lib/docscribe/infer/constants.rb +11 -0
- data/lib/docscribe/infer/literals.rb +55 -0
- data/lib/docscribe/infer/names.rb +43 -0
- data/lib/docscribe/infer/params.rb +62 -0
- data/lib/docscribe/infer/raises.rb +68 -0
- data/lib/docscribe/infer/returns.rb +171 -0
- data/lib/docscribe/infer.rb +110 -259
- data/lib/docscribe/inline_rewriter/collector.rb +845 -0
- data/lib/docscribe/inline_rewriter/doc_block.rb +383 -0
- data/lib/docscribe/inline_rewriter/doc_builder.rb +605 -0
- data/lib/docscribe/inline_rewriter/source_helpers.rb +228 -0
- data/lib/docscribe/inline_rewriter/tag_sorter.rb +244 -0
- data/lib/docscribe/inline_rewriter.rb +604 -425
- data/lib/docscribe/parsing.rb +120 -0
- data/lib/docscribe/types/provider_chain.rb +37 -0
- data/lib/docscribe/types/rbs/provider.rb +213 -0
- data/lib/docscribe/types/rbs/type_formatter.rb +132 -0
- data/lib/docscribe/types/signature.rb +65 -0
- data/lib/docscribe/types/sorbet/base_provider.rb +217 -0
- data/lib/docscribe/types/sorbet/rbi_provider.rb +35 -0
- data/lib/docscribe/types/sorbet/source_provider.rb +25 -0
- data/lib/docscribe/version.rb +1 -1
- data/lib/docscribe.rb +1 -0
- metadata +85 -17
- data/.rspec +0 -3
- data/.rubocop.yml +0 -11
- data/.rubocop_todo.yml +0 -73
- data/CODE_OF_CONDUCT.md +0 -84
- data/Gemfile +0 -6
- data/Gemfile.lock +0 -73
- data/Rakefile +0 -12
- data/rakelib/docs.rake +0 -73
- data/stingray_docs_internal.gemspec +0 -41
data/README.md
CHANGED
|
@@ -4,32 +4,72 @@
|
|
|
4
4
|
[](https://rubygems.org/gems/docscribe)
|
|
5
5
|
[](https://github.com/unurgunite/docscribe/actions/workflows/ci.yml)
|
|
6
6
|
[](https://github.com/unurgunite/docscribe/blob/master/LICENSE.txt)
|
|
7
|
-
[](#installation)
|
|
8
8
|
|
|
9
|
-
Generate inline, YARD-style documentation comments for Ruby methods by analyzing your code's AST.
|
|
10
|
-
headers before method definitions, infers parameter and return types (including rescue-aware returns), and respects Ruby
|
|
11
|
-
visibility semantics — without using YARD to parse.
|
|
9
|
+
Generate inline, YARD-style documentation comments for Ruby methods by analyzing your code's AST.
|
|
12
10
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
- Heuristic type inference for params and return values, including conditional returns in rescue branches.
|
|
16
|
-
- Optional rewrite mode for regenerating existing method docs.
|
|
11
|
+
Docscribe inserts doc headers before method definitions, infers parameter and return types (including rescue-aware
|
|
12
|
+
returns), and respects Ruby visibility semantics — without using YARD to parse.
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
- No AST reprinting. Your original code, formatting, and constructs (like `class << self`, `heredocs`, `%i[]`) are
|
|
15
|
+
preserved.
|
|
16
|
+
- Inline-first. Comments are inserted before method headers without reprinting the AST. For methods with a leading
|
|
17
|
+
Sorbet `sig`, new docs are inserted above the first `sig`.
|
|
18
|
+
- Heuristic type inference for params and return values, including conditional returns in rescue branches.
|
|
19
|
+
- Safe and aggressive update modes:
|
|
20
|
+
- safe mode inserts missing docs, merges existing doc-like blocks, and normalizes sortable tags;
|
|
21
|
+
- aggressive mode rebuilds existing doc blocks.
|
|
22
|
+
- Ruby 3.4+ syntax supported using Prism translation (see "Parser backend" below).
|
|
23
|
+
- Optional external type integrations:
|
|
24
|
+
- RBS via `--rbs` / `--sig-dir`;
|
|
25
|
+
- Sorbet via inline `sig` declarations and RBI files with `--sorbet` / `--rbi-dir`.
|
|
26
|
+
- Optional `@!attribute` generation for:
|
|
27
|
+
- `attr_reader` / `attr_writer` / `attr_accessor`;
|
|
28
|
+
- `Struct.new` declarations in both constant-assigned and class-based styles.
|
|
29
|
+
|
|
30
|
+
Common workflows:
|
|
31
|
+
|
|
32
|
+
- Inspect what safe doc updates would be applied: `docscribe lib`
|
|
33
|
+
- Apply safe doc updates: `docscribe -a lib`
|
|
34
|
+
- Apply aggressive doc updates: `docscribe -A lib`
|
|
35
|
+
- Use RBS signatures when available: `docscribe -a --rbs --sig-dir sig lib`
|
|
36
|
+
- Use Sorbet signatures when available: `docscribe -a --sorbet --rbi-dir sorbet/rbi lib`
|
|
37
|
+
|
|
38
|
+
## Contents
|
|
20
39
|
|
|
21
40
|
* [Docscribe](#docscribe)
|
|
41
|
+
* [Contents](#contents)
|
|
22
42
|
* [Installation](#installation)
|
|
23
43
|
* [Quick start](#quick-start)
|
|
24
44
|
* [CLI](#cli)
|
|
25
|
-
|
|
26
|
-
* [
|
|
45
|
+
* [Options](#options)
|
|
46
|
+
* [Examples](#examples)
|
|
47
|
+
* [Update strategies](#update-strategies)
|
|
48
|
+
* [Safe strategy](#safe-strategy)
|
|
49
|
+
* [Aggressive strategy](#aggressive-strategy)
|
|
50
|
+
* [Output markers](#output-markers)
|
|
51
|
+
* [Parser backend (Parser gem vs Prism)](#parser-backend-parser-gem-vs-prism)
|
|
52
|
+
* [External type integrations (optional)](#external-type-integrations-optional)
|
|
53
|
+
* [RBS](#rbs)
|
|
54
|
+
* [Sorbet](#sorbet)
|
|
55
|
+
* [Inline Sorbet example](#inline-sorbet-example)
|
|
56
|
+
* [Sorbet RBI example](#sorbet-rbi-example)
|
|
57
|
+
* [Sorbet comment placement](#sorbet-comment-placement)
|
|
58
|
+
* [Generic type formatting](#generic-type-formatting)
|
|
59
|
+
* [Notes and fallback behavior](#notes-and-fallback-behavior)
|
|
27
60
|
* [Type inference](#type-inference)
|
|
28
61
|
* [Rescue-aware returns and @raise](#rescue-aware-returns-and-raise)
|
|
29
62
|
* [Visibility semantics](#visibility-semantics)
|
|
30
63
|
* [API (library) usage](#api-library-usage)
|
|
31
64
|
* [Configuration](#configuration)
|
|
32
|
-
* [
|
|
65
|
+
* [Filtering](#filtering)
|
|
66
|
+
* [`attr_*` example](#attr_-example)
|
|
67
|
+
* [`Struct.new` examples](#structnew-examples)
|
|
68
|
+
* [Constant-assigned struct](#constant-assigned-struct)
|
|
69
|
+
* [Class-based struct](#class-based-struct)
|
|
70
|
+
* [Merge behavior](#merge-behavior)
|
|
71
|
+
* [Param tag style](#param-tag-style)
|
|
72
|
+
* [Create a starter config](#create-a-starter-config)
|
|
33
73
|
* [CI integration](#ci-integration)
|
|
34
74
|
* [Comparison to YARD's parser](#comparison-to-yards-parser)
|
|
35
75
|
* [Limitations](#limitations)
|
|
@@ -42,7 +82,7 @@ source structure and exact control over Ruby semantics.
|
|
|
42
82
|
Add to your Gemfile:
|
|
43
83
|
|
|
44
84
|
```ruby
|
|
45
|
-
gem
|
|
85
|
+
gem "docscribe"
|
|
46
86
|
```
|
|
47
87
|
|
|
48
88
|
Then:
|
|
@@ -57,7 +97,7 @@ Or install globally:
|
|
|
57
97
|
gem install docscribe
|
|
58
98
|
```
|
|
59
99
|
|
|
60
|
-
Requires Ruby
|
|
100
|
+
Requires Ruby 2.7+.
|
|
61
101
|
|
|
62
102
|
## Quick start
|
|
63
103
|
|
|
@@ -97,7 +137,6 @@ echo "...code above..." | docscribe --stdin
|
|
|
97
137
|
Output:
|
|
98
138
|
|
|
99
139
|
```ruby
|
|
100
|
-
|
|
101
140
|
class Demo
|
|
102
141
|
# +Demo#foo+ -> Integer
|
|
103
142
|
#
|
|
@@ -145,11 +184,11 @@ class Demo
|
|
|
145
184
|
end
|
|
146
185
|
```
|
|
147
186
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
-
|
|
151
|
-
- Class methods show with a dot (`+Demo.bump+`, `+Demo.internal+`).
|
|
152
|
-
- Methods inside `class << self` under private are marked `@private
|
|
187
|
+
> [!NOTE]
|
|
188
|
+
> - The tool inserts doc headers before method headers and preserves everything else.
|
|
189
|
+
> - For methods with a leading Sorbet `sig`, docs are inserted above the first `sig`.
|
|
190
|
+
> - Class methods show with a dot (`+Demo.bump+`, `+Demo.internal+`).
|
|
191
|
+
> - Methods inside `class << self` under `private` are marked `@private`.
|
|
153
192
|
|
|
154
193
|
## CLI
|
|
155
194
|
|
|
@@ -157,158 +196,492 @@ Notes:
|
|
|
157
196
|
docscribe [options] [files...]
|
|
158
197
|
```
|
|
159
198
|
|
|
160
|
-
|
|
199
|
+
Docscribe has three main ways to run:
|
|
200
|
+
|
|
201
|
+
- **Inspect mode** (default): checks what safe doc updates would be applied and exits non-zero if files need changes.
|
|
202
|
+
- **Safe autocorrect** (`-a`, `--autocorrect`): writes safe, non-destructive updates in place.
|
|
203
|
+
- **Aggressive autocorrect** (`-A`, `--autocorrect-all`): rewrites existing doc blocks more aggressively.
|
|
204
|
+
- **STDIN mode** (`--stdin`): reads Ruby source from STDIN and prints rewritten source to STDOUT.
|
|
205
|
+
|
|
206
|
+
If you pass no files and don’t use `--stdin`, Docscribe processes the current directory recursively.
|
|
207
|
+
|
|
208
|
+
### Options
|
|
209
|
+
|
|
210
|
+
- `-a`, `--autocorrect`
|
|
211
|
+
Apply safe doc updates in place.
|
|
212
|
+
|
|
213
|
+
- `-A`, `--autocorrect-all`
|
|
214
|
+
Apply aggressive doc updates in place.
|
|
215
|
+
|
|
216
|
+
- `--stdin`
|
|
217
|
+
Read source from STDIN and print rewritten output.
|
|
218
|
+
|
|
219
|
+
- `--verbose`
|
|
220
|
+
Print per-file actions.
|
|
221
|
+
|
|
222
|
+
- `--explain`
|
|
223
|
+
Show detailed reasons for each file that would change.
|
|
224
|
+
|
|
225
|
+
- `--rbs`
|
|
226
|
+
Use RBS signatures for `@param`/`@return` when available (falls back to inference).
|
|
227
|
+
|
|
228
|
+
- `--sig-dir DIR`
|
|
229
|
+
Add an RBS signature directory (repeatable). Implies `--rbs`.
|
|
230
|
+
|
|
231
|
+
- `--include PATTERN`
|
|
232
|
+
Include PATTERN (method id or file path; glob or `/regex/`).
|
|
233
|
+
|
|
234
|
+
- `--exclude PATTERN`
|
|
235
|
+
Exclude PATTERN (method id or file path; glob or `/regex/`). Exclude wins.
|
|
236
|
+
|
|
237
|
+
- `--include-file PATTERN`
|
|
238
|
+
Only process files matching PATTERN (glob or `/regex/`).
|
|
239
|
+
|
|
240
|
+
- `--exclude-file PATTERN`
|
|
241
|
+
Skip files matching PATTERN (glob or `/regex/`). Exclude wins.
|
|
242
|
+
|
|
243
|
+
- `-C`, `--config PATH`
|
|
244
|
+
Path to config YAML (default: `docscribe.yml`).
|
|
245
|
+
|
|
246
|
+
- `-v`, `--version`
|
|
247
|
+
Print version and exit.
|
|
161
248
|
|
|
162
|
-
- `--
|
|
163
|
-
|
|
164
|
-
- `--check` Dry-run: exit 1 if any file would change (useful in CI).
|
|
165
|
-
- `--rewrite` Replace any existing comment block above methods (see “Rewrite mode” below).
|
|
166
|
-
- `--version` Print version and exit.
|
|
167
|
-
- `-h`, `--help` Show help.
|
|
249
|
+
- `-h`, `--help`
|
|
250
|
+
Show help.
|
|
168
251
|
|
|
169
|
-
Examples
|
|
252
|
+
### Examples
|
|
170
253
|
|
|
171
|
-
-
|
|
254
|
+
- Inspect a directory:
|
|
172
255
|
```shell
|
|
173
|
-
docscribe
|
|
256
|
+
docscribe lib
|
|
174
257
|
```
|
|
175
|
-
|
|
258
|
+
|
|
259
|
+
- Apply safe updates:
|
|
176
260
|
```shell
|
|
177
|
-
docscribe
|
|
261
|
+
docscribe -a lib
|
|
178
262
|
```
|
|
179
|
-
|
|
263
|
+
|
|
264
|
+
- Apply aggressive updates:
|
|
180
265
|
```shell
|
|
181
|
-
docscribe
|
|
266
|
+
docscribe -A lib
|
|
182
267
|
```
|
|
183
|
-
|
|
268
|
+
|
|
269
|
+
- Preview output for a single file via STDIN:
|
|
184
270
|
```shell
|
|
185
|
-
docscribe --
|
|
271
|
+
cat path/to/file.rb | docscribe --stdin
|
|
186
272
|
```
|
|
187
273
|
|
|
188
|
-
|
|
274
|
+
- Use RBS signatures:
|
|
275
|
+
```shell
|
|
276
|
+
docscribe -a --rbs --sig-dir sig lib
|
|
277
|
+
```
|
|
189
278
|
|
|
190
|
-
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
279
|
+
- Show detailed reasons for files that would change:
|
|
280
|
+
```shell
|
|
281
|
+
docscribe --verbose --explain lib
|
|
282
|
+
```
|
|
194
283
|
|
|
195
|
-
|
|
284
|
+
## Update strategies
|
|
196
285
|
|
|
197
|
-
|
|
198
|
-
blank
|
|
199
|
-
lines) and replace it with a fresh generated block.
|
|
200
|
-
- This is useful to refresh docs across a codebase after improving inference or rules.
|
|
201
|
-
- Use with caution (prefer a clean working tree and review diffs).
|
|
286
|
+
Docscribe supports two update strategies: **safe** and **aggressive**.
|
|
202
287
|
|
|
203
|
-
|
|
288
|
+
### Safe strategy
|
|
204
289
|
|
|
205
|
-
|
|
290
|
+
Used by:
|
|
206
291
|
|
|
207
|
-
|
|
292
|
+
- default inspect mode: `docscribe lib`
|
|
293
|
+
- safe write mode: `docscribe -a lib`
|
|
208
294
|
|
|
209
|
-
|
|
210
|
-
- `**kwargs` -> `Hash`
|
|
211
|
-
- `&block` -> `Proc`
|
|
212
|
-
- keyword args:
|
|
213
|
-
- verbose: `true` -> `Boolean`
|
|
214
|
-
- options: `{}` -> `Hash`
|
|
215
|
-
- kw: (no default) -> `Object`
|
|
216
|
-
- positional defaults:
|
|
217
|
-
- `42` -> `Integer`, `1.0` -> `Float`, `'x'` -> `String`, `:ok` -> `Symbol`
|
|
218
|
-
- `[]` -> `Array`, `{}` -> `Hash`, `/x/` -> `Regexp`, `true`/`false` -> `Boolean`, `nil` -> `nil`
|
|
295
|
+
Safe strategy:
|
|
219
296
|
|
|
220
|
-
|
|
297
|
+
- inserts docs for undocumented methods
|
|
298
|
+
- merges missing tags into existing **doc-like** blocks
|
|
299
|
+
- normalizes configurable tag order inside sortable tag runs
|
|
300
|
+
- preserves existing prose and comments where possible
|
|
221
301
|
|
|
222
|
-
|
|
223
|
-
- `42` -> `Integer`
|
|
224
|
-
- `:ok` -> `Symbol`
|
|
225
|
-
- Unions with nil become optional types (e.g., `String` or `nil` -> `String?`).
|
|
226
|
-
- For control flow (`if`/`case`), it unifies branches conservatively.
|
|
302
|
+
This is the recommended day-to-day mode.
|
|
227
303
|
|
|
228
|
-
|
|
304
|
+
### Aggressive strategy
|
|
229
305
|
|
|
230
|
-
|
|
306
|
+
Used by:
|
|
231
307
|
|
|
232
|
-
-
|
|
233
|
-
- `rescue Foo, Bar` -> `@raise [Foo]` and `@raise [Bar]`
|
|
234
|
-
- bare rescue -> `@raise [StandardError]`
|
|
235
|
-
- (optional) explicit raise/fail also adds a tag (`raise Foo` -> `@raise [Foo]`, `raise` ->
|
|
236
|
-
`@raise [StandardError]`).
|
|
308
|
+
- aggressive write mode: `docscribe -A lib`
|
|
237
309
|
|
|
238
|
-
|
|
239
|
-
|
|
310
|
+
Aggressive strategy:
|
|
311
|
+
|
|
312
|
+
- rebuilds existing doc blocks
|
|
313
|
+
- replaces existing generated documentation more fully
|
|
314
|
+
- is more invasive than safe mode
|
|
315
|
+
|
|
316
|
+
Use it when you want to rebaseline or regenerate docs wholesale.
|
|
317
|
+
|
|
318
|
+
### Output markers
|
|
319
|
+
|
|
320
|
+
In inspect mode, Docscribe prints one character per file:
|
|
321
|
+
|
|
322
|
+
- `.` = file is up to date
|
|
323
|
+
- `F` = file would change
|
|
324
|
+
- `E` = file had an error
|
|
325
|
+
|
|
326
|
+
In write modes:
|
|
327
|
+
|
|
328
|
+
- `.` = file already OK
|
|
329
|
+
- `C` = file was updated
|
|
330
|
+
- `E` = file had an error
|
|
331
|
+
|
|
332
|
+
With `--verbose`, Docscribe prints per-file statuses instead.
|
|
333
|
+
|
|
334
|
+
With `--explain`, Docscribe also prints detailed reasons, such as:
|
|
335
|
+
|
|
336
|
+
- missing `@param`
|
|
337
|
+
- missing `@return`
|
|
338
|
+
- missing module_function note
|
|
339
|
+
- unsorted tags
|
|
340
|
+
|
|
341
|
+
## Parser backend (Parser gem vs Prism)
|
|
342
|
+
|
|
343
|
+
Docscribe internally works with `parser`-gem-compatible AST nodes and `Parser::Source::*` objects (so it can use
|
|
344
|
+
`Parser::Source::TreeRewriter` without changing formatting).
|
|
345
|
+
|
|
346
|
+
- On Ruby **<= 3.3**, Docscribe parses using the `parser` gem.
|
|
347
|
+
- On Ruby **>= 3.4**, Docscribe parses using **Prism** and translates the tree into the `parser` gem's AST.
|
|
348
|
+
|
|
349
|
+
You can force a backend with an environment variable:
|
|
350
|
+
|
|
351
|
+
```shell
|
|
352
|
+
DOCSCRIBE_PARSER_BACKEND=parser bundle exec docscribe lib
|
|
353
|
+
DOCSCRIBE_PARSER_BACKEND=prism bundle exec docscribe lib
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
## External type integrations (optional)
|
|
357
|
+
|
|
358
|
+
Docscribe can improve generated `@param` and `@return` types by reading external signatures instead of relying only on
|
|
359
|
+
AST inference.
|
|
360
|
+
|
|
361
|
+
> [!IMPORTANT]
|
|
362
|
+
> When external type information is available, Docscribe resolves signatures in this order:
|
|
363
|
+
> - inline Sorbet `sig` declarations in the current Ruby source;
|
|
364
|
+
> - Sorbet RBI files;
|
|
365
|
+
> - RBS files;
|
|
366
|
+
> - AST inference fallback.
|
|
367
|
+
>
|
|
368
|
+
> If an external signature cannot be loaded or parsed, Docscribe falls back to normal inference instead of failing.
|
|
369
|
+
|
|
370
|
+
### RBS
|
|
371
|
+
|
|
372
|
+
Docscribe can read method signatures from `.rbs` files and use them to generate more accurate parameter and return
|
|
373
|
+
types.
|
|
374
|
+
|
|
375
|
+
CLI:
|
|
376
|
+
|
|
377
|
+
```shell
|
|
378
|
+
docscribe -a --rbs --sig-dir sig lib
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
You can pass `--sig-dir` multiple times:
|
|
382
|
+
|
|
383
|
+
```shell
|
|
384
|
+
docscribe -a --rbs --sig-dir sig --sig-dir vendor/sigs lib
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
Config:
|
|
388
|
+
|
|
389
|
+
```yaml
|
|
390
|
+
rbs:
|
|
391
|
+
enabled: true
|
|
392
|
+
sig_dirs:
|
|
393
|
+
- sig
|
|
394
|
+
collapse_generics: false
|
|
395
|
+
```
|
|
240
396
|
|
|
241
397
|
Example:
|
|
242
398
|
|
|
243
399
|
```ruby
|
|
400
|
+
# Ruby source
|
|
401
|
+
class Demo
|
|
402
|
+
def foo(verbose:, count:)
|
|
403
|
+
"body says String"
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
```
|
|
244
407
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
408
|
+
```ruby.rbs
|
|
409
|
+
# sig/demo.rbs
|
|
410
|
+
class Demo
|
|
411
|
+
def foo: (verbose: bool, count: Integer) -> Integer
|
|
412
|
+
end
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
Generated docs will prefer the RBS signature over inferred Ruby types:
|
|
416
|
+
|
|
417
|
+
```ruby
|
|
418
|
+
|
|
419
|
+
class Demo
|
|
420
|
+
# +Demo#foo+ -> Integer
|
|
421
|
+
#
|
|
422
|
+
# Method documentation.
|
|
423
|
+
#
|
|
424
|
+
# @param [Boolean] verbose Param documentation.
|
|
425
|
+
# @param [Integer] count Param documentation.
|
|
426
|
+
# @return [Integer]
|
|
427
|
+
def foo(verbose:, count:)
|
|
428
|
+
'body says String'
|
|
250
429
|
end
|
|
430
|
+
end
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Sorbet
|
|
434
|
+
|
|
435
|
+
Docscribe can also read Sorbet signatures from:
|
|
436
|
+
|
|
437
|
+
- inline `sig` declarations in Ruby source
|
|
438
|
+
- RBI files
|
|
439
|
+
|
|
440
|
+
CLI:
|
|
251
441
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
442
|
+
```shell
|
|
443
|
+
docscribe -a --sorbet lib
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
With RBI directories:
|
|
447
|
+
|
|
448
|
+
```shell
|
|
449
|
+
docscribe -a --sorbet --rbi-dir sorbet/rbi lib
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
You can pass `--rbi-dir` multiple times:
|
|
453
|
+
|
|
454
|
+
```shell
|
|
455
|
+
docscribe -a --sorbet --rbi-dir sorbet/rbi --rbi-dir rbi lib
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
Config:
|
|
459
|
+
|
|
460
|
+
```yaml
|
|
461
|
+
sorbet:
|
|
462
|
+
enabled: true
|
|
463
|
+
rbi_dirs:
|
|
464
|
+
- sorbet/rbi
|
|
465
|
+
- rbi
|
|
466
|
+
collapse_generics: false
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### Inline Sorbet example
|
|
470
|
+
|
|
471
|
+
```ruby
|
|
472
|
+
class Demo
|
|
473
|
+
extend T::Sig
|
|
474
|
+
|
|
475
|
+
sig { params(verbose: T::Boolean, count: Integer).returns(Integer) }
|
|
476
|
+
def foo(verbose:, count:)
|
|
477
|
+
'body says String'
|
|
256
478
|
end
|
|
257
479
|
end
|
|
258
480
|
```
|
|
259
481
|
|
|
260
|
-
|
|
482
|
+
Docscribe will use the Sorbet signature instead of the inferred body type:
|
|
261
483
|
|
|
262
484
|
```ruby
|
|
485
|
+
class Demo
|
|
486
|
+
extend T::Sig
|
|
263
487
|
|
|
264
|
-
|
|
265
|
-
# +X#a+ -> Integer
|
|
488
|
+
# +Demo#foo+ -> Integer
|
|
266
489
|
#
|
|
267
490
|
# Method documentation.
|
|
268
491
|
#
|
|
269
|
-
# @
|
|
270
|
-
# @
|
|
492
|
+
# @param [Boolean] verbose Param documentation.
|
|
493
|
+
# @param [Integer] count Param documentation.
|
|
271
494
|
# @return [Integer]
|
|
272
|
-
|
|
273
|
-
def
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
495
|
+
sig { params(verbose: T::Boolean, count: Integer).returns(Integer) }
|
|
496
|
+
def foo(verbose:, count:)
|
|
497
|
+
'body says String'
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
### Sorbet RBI example
|
|
503
|
+
|
|
504
|
+
```ruby
|
|
505
|
+
# Ruby source
|
|
506
|
+
class Demo
|
|
507
|
+
def foo(verbose:, count:)
|
|
508
|
+
'body says String'
|
|
509
|
+
end
|
|
510
|
+
end
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
```ruby
|
|
514
|
+
# sorbet/rbi/demo.rbi
|
|
515
|
+
class Demo
|
|
516
|
+
extend T::Sig
|
|
517
|
+
|
|
518
|
+
sig { params(verbose: T::Boolean, count: Integer).returns(Integer) }
|
|
519
|
+
def foo(verbose:, count:); end
|
|
520
|
+
end
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
With:
|
|
524
|
+
|
|
525
|
+
```shell
|
|
526
|
+
docscribe -a --sorbet --rbi-dir sorbet/rbi lib
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
Docscribe will use the RBI signature for generated docs.
|
|
530
|
+
|
|
531
|
+
### Sorbet comment placement
|
|
532
|
+
|
|
533
|
+
For methods with a leading Sorbet `sig`, Docscribe treats the signature as part of the method header.
|
|
534
|
+
|
|
535
|
+
That means:
|
|
536
|
+
|
|
537
|
+
- new docs are inserted **above the first `sig`**
|
|
538
|
+
- existing docs **above the `sig`** are recognized and merged
|
|
539
|
+
- existing legacy docs **between `sig` and `def`** are also recognized
|
|
540
|
+
|
|
541
|
+
Example input:
|
|
542
|
+
|
|
543
|
+
```ruby
|
|
544
|
+
# demo.rb
|
|
545
|
+
class Demo
|
|
546
|
+
extend T::Sig
|
|
547
|
+
|
|
548
|
+
sig { returns(Integer) }
|
|
549
|
+
def foo
|
|
550
|
+
1
|
|
277
551
|
end
|
|
552
|
+
end
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
Example output:
|
|
556
|
+
|
|
557
|
+
```ruby
|
|
558
|
+
# demo.rb
|
|
559
|
+
class Demo
|
|
560
|
+
extend T::Sig
|
|
278
561
|
|
|
279
|
-
# +
|
|
562
|
+
# +Demo#foo+ -> Integer
|
|
280
563
|
#
|
|
281
564
|
# Method documentation.
|
|
282
565
|
#
|
|
283
|
-
# @
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
risky
|
|
288
|
-
rescue
|
|
289
|
-
"n"
|
|
566
|
+
# @return [Integer]
|
|
567
|
+
sig { returns(Integer) }
|
|
568
|
+
def foo
|
|
569
|
+
1
|
|
290
570
|
end
|
|
291
571
|
end
|
|
292
572
|
```
|
|
293
573
|
|
|
574
|
+
### Generic type formatting
|
|
575
|
+
|
|
576
|
+
Both RBS and Sorbet integrations support `collapse_generics`.
|
|
577
|
+
|
|
578
|
+
When disabled:
|
|
579
|
+
|
|
580
|
+
```yaml
|
|
581
|
+
rbs:
|
|
582
|
+
collapse_generics: false
|
|
583
|
+
|
|
584
|
+
sorbet:
|
|
585
|
+
collapse_generics: false
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
Docscribe preserves generic container details where possible, for example:
|
|
589
|
+
|
|
590
|
+
- `Array<String>`
|
|
591
|
+
- `Hash<Symbol, Integer>`
|
|
592
|
+
|
|
593
|
+
When enabled:
|
|
594
|
+
|
|
595
|
+
```yaml
|
|
596
|
+
rbs:
|
|
597
|
+
collapse_generics: true
|
|
598
|
+
|
|
599
|
+
sorbet:
|
|
600
|
+
collapse_generics: true
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
Docscribe simplifies container types to their outer names, for example:
|
|
604
|
+
|
|
605
|
+
- `Array`
|
|
606
|
+
- `Hash`
|
|
607
|
+
|
|
608
|
+
### Notes and fallback behavior
|
|
609
|
+
|
|
610
|
+
- External signature support is the **best effort**.
|
|
611
|
+
- If a signature source cannot be loaded or parsed, Docscribe falls back to AST inference.
|
|
612
|
+
- RBS and Sorbet integrations are used only to improve generated types; Docscribe still rewrites Ruby source directly.
|
|
613
|
+
- Sorbet support does not require changing your documentation style — it only improves generated `@param` and `@return`
|
|
614
|
+
tags when signatures are available.
|
|
615
|
+
|
|
616
|
+
## Type inference
|
|
617
|
+
|
|
618
|
+
Heuristics (best-effort).
|
|
619
|
+
|
|
620
|
+
Parameters:
|
|
621
|
+
|
|
622
|
+
- `*args` -> `Array`
|
|
623
|
+
- `**kwargs` -> `Hash`
|
|
624
|
+
- `&block` -> `Proc`
|
|
625
|
+
- keyword args:
|
|
626
|
+
- `verbose: true` -> `Boolean`
|
|
627
|
+
- `options: {}` -> `Hash`
|
|
628
|
+
- `kw:` (no default) -> `Object`
|
|
629
|
+
- positional defaults:
|
|
630
|
+
- `42` -> `Integer`, `1.0` -> `Float`, `'x'` -> `String`, `:ok` -> `Symbol`
|
|
631
|
+
- `[]` -> `Array`, `{}` -> `Hash`, `/x/` -> `Regexp`, `true`/`false` -> `Boolean`, `nil` -> `nil`
|
|
632
|
+
|
|
633
|
+
Return values:
|
|
634
|
+
|
|
635
|
+
- For simple bodies, Docscribe looks at the last expression or explicit `return`.
|
|
636
|
+
- Unions with `nil` become optional types (e.g. `String` or `nil` -> `String?`).
|
|
637
|
+
- For control flow (`if`/`case`), it unifies branches conservatively.
|
|
638
|
+
|
|
639
|
+
## Rescue-aware returns and @raise
|
|
640
|
+
|
|
641
|
+
Docscribe detects exceptions and rescue branches:
|
|
642
|
+
|
|
643
|
+
- Rescue exceptions become `@raise` tags:
|
|
644
|
+
- `rescue Foo, Bar` -> `@raise [Foo]` and `@raise [Bar]`
|
|
645
|
+
- bare rescue -> `@raise [StandardError]`
|
|
646
|
+
- explicit `raise`/`fail` also adds a tag (`raise Foo` -> `@raise [Foo]`, `raise` -> `@raise [StandardError]`)
|
|
647
|
+
|
|
648
|
+
- Conditional return types for rescue branches:
|
|
649
|
+
- Docscribe adds `@return [Type] if ExceptionA, ExceptionB` for each rescue clause
|
|
650
|
+
|
|
294
651
|
## Visibility semantics
|
|
295
652
|
|
|
296
653
|
We match Ruby's behavior:
|
|
297
654
|
|
|
298
655
|
- A bare `private`/`protected`/`public` in a class/module body affects instance methods only.
|
|
299
656
|
- Inside `class << self`, a bare visibility keyword affects class methods only.
|
|
300
|
-
- `def self.x` in a class body remains `public` unless `private_class_method` is used or it's inside `class << self`
|
|
301
|
-
`private`.
|
|
657
|
+
- `def self.x` in a class body remains `public` unless `private_class_method` is used, or it's inside `class << self`
|
|
658
|
+
under `private`.
|
|
302
659
|
|
|
303
660
|
Inline tags:
|
|
304
661
|
|
|
305
662
|
- `@private` is added for methods that are private in context.
|
|
306
663
|
- `@protected` is added similarly for protected methods.
|
|
307
664
|
|
|
665
|
+
> [!IMPORTANT]
|
|
666
|
+
> `module_function`: Docscribe documents methods affected by `module_function` as module methods (`M.foo`) rather than
|
|
667
|
+
> instance methods (`M#foo`), because that is usually the callable/public API. If a method was previously private as an
|
|
668
|
+
> instance method, Docscribe will avoid marking the generated docs as `@private` after it is promoted to a module
|
|
669
|
+
> method.
|
|
670
|
+
|
|
671
|
+
```ruby
|
|
672
|
+
module M
|
|
673
|
+
private
|
|
674
|
+
|
|
675
|
+
def foo; end
|
|
676
|
+
|
|
677
|
+
module_function :foo
|
|
678
|
+
end
|
|
679
|
+
```
|
|
680
|
+
|
|
308
681
|
## API (library) usage
|
|
309
682
|
|
|
310
683
|
```ruby
|
|
311
|
-
require
|
|
684
|
+
require "docscribe/inline_rewriter"
|
|
312
685
|
|
|
313
686
|
code = <<~RUBY
|
|
314
687
|
class Demo
|
|
@@ -317,135 +690,274 @@ code = <<~RUBY
|
|
|
317
690
|
end
|
|
318
691
|
RUBY
|
|
319
692
|
|
|
320
|
-
#
|
|
693
|
+
# Basic insertion behavior
|
|
321
694
|
out = Docscribe::InlineRewriter.insert_comments(code)
|
|
322
695
|
puts out
|
|
323
696
|
|
|
324
|
-
#
|
|
325
|
-
out2 = Docscribe::InlineRewriter.insert_comments(code,
|
|
697
|
+
# Safe merge / normalization of existing doc-like blocks
|
|
698
|
+
out2 = Docscribe::InlineRewriter.insert_comments(code, strategy: :safe)
|
|
699
|
+
|
|
700
|
+
# Aggressive rebuild of existing doc blocks (similar to CLI -A)
|
|
701
|
+
out3 = Docscribe::InlineRewriter.insert_comments(code, strategy: :aggressive)
|
|
326
702
|
```
|
|
327
703
|
|
|
328
704
|
## Configuration
|
|
329
705
|
|
|
330
|
-
Docscribe can be configured via a YAML file (docscribe.yml by default, or pass
|
|
706
|
+
Docscribe can be configured via a YAML file (`docscribe.yml` by default, or pass `--config PATH`).
|
|
707
|
+
|
|
708
|
+
### Filtering
|
|
709
|
+
|
|
710
|
+
Docscribe can filter both *files* and *methods*.
|
|
711
|
+
|
|
712
|
+
File filtering (recommended for excluding specs, vendor code, etc.):
|
|
713
|
+
|
|
714
|
+
```yaml
|
|
715
|
+
filter:
|
|
716
|
+
files:
|
|
717
|
+
exclude: [ "spec" ]
|
|
718
|
+
```
|
|
719
|
+
|
|
720
|
+
Method filtering matches method ids like:
|
|
721
|
+
|
|
722
|
+
- `MyModule::MyClass#instance_method`
|
|
723
|
+
- `MyModule::MyClass.class_method`
|
|
331
724
|
|
|
332
725
|
Example:
|
|
333
726
|
|
|
727
|
+
```yaml
|
|
728
|
+
filter:
|
|
729
|
+
exclude:
|
|
730
|
+
- "*#initialize"
|
|
731
|
+
```
|
|
732
|
+
|
|
733
|
+
CLI overrides are available too:
|
|
734
|
+
|
|
735
|
+
```shell
|
|
736
|
+
# Method filtering (matches method ids like A#foo / A.bar)
|
|
737
|
+
docscribe --exclude '*#initialize' lib
|
|
738
|
+
docscribe --include '/^MyModule::.*#(foo|bar)$/' lib
|
|
739
|
+
|
|
740
|
+
# File filtering (matches paths relative to the project root)
|
|
741
|
+
docscribe --exclude-file 'spec' lib spec
|
|
742
|
+
docscribe --exclude-file '/^spec\//' lib
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
> [!NOTE]
|
|
746
|
+
> `/regex/` passed to `--include`/`--exclude` is treated as a **method-id** pattern. Use `--include-file` /
|
|
747
|
+
`--exclude-file` for file regex filters.
|
|
748
|
+
|
|
749
|
+
Enable attribute-style documentation generation with:
|
|
750
|
+
|
|
334
751
|
```yaml
|
|
335
752
|
emit:
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
753
|
+
attributes: true
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
When enabled, Docscribe can generate YARD `@!attribute` docs for:
|
|
757
|
+
|
|
758
|
+
- `attr_reader`
|
|
759
|
+
- `attr_writer`
|
|
760
|
+
- `attr_accessor`
|
|
761
|
+
- `Struct.new` declarations
|
|
762
|
+
|
|
763
|
+
### `attr_*` example
|
|
764
|
+
|
|
765
|
+
> [!NOTE]
|
|
766
|
+
> - Attribute docs are inserted above the `attr_*` call, not above generated methods (since they don’t exist as `def`
|
|
767
|
+
nodes).
|
|
768
|
+
> - If RBS is enabled, Docscribe will try to use the RBS return type of the reader method as the attribute type.
|
|
769
|
+
|
|
770
|
+
```ruby
|
|
771
|
+
class User
|
|
772
|
+
attr_accessor :name
|
|
773
|
+
end
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
Generated docs:
|
|
777
|
+
|
|
778
|
+
```ruby
|
|
779
|
+
class User
|
|
780
|
+
# @!attribute [rw] name
|
|
781
|
+
# @return [Object]
|
|
782
|
+
# @param [Object] value
|
|
783
|
+
attr_accessor :name
|
|
784
|
+
end
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
### `Struct.new` examples
|
|
788
|
+
|
|
789
|
+
Docscribe supports both common `Struct.new` declaration styles.
|
|
790
|
+
|
|
791
|
+
#### Constant-assigned struct
|
|
792
|
+
|
|
793
|
+
```ruby
|
|
794
|
+
User = Struct.new(:name, :email, keyword_init: true)
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
Generated docs:
|
|
798
|
+
|
|
799
|
+
```ruby
|
|
800
|
+
# @!attribute [rw] name
|
|
801
|
+
# @return [Object]
|
|
802
|
+
# @param [Object] value
|
|
803
|
+
#
|
|
804
|
+
# @!attribute [rw] email
|
|
805
|
+
# @return [Object]
|
|
806
|
+
# @param [Object] value
|
|
807
|
+
User = Struct.new(:name, :email, keyword_init: true)
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
#### Class-based struct
|
|
811
|
+
|
|
812
|
+
```ruby
|
|
813
|
+
class User < Struct.new(:name, :email, keyword_init: true)
|
|
814
|
+
end
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
Generated docs:
|
|
818
|
+
|
|
819
|
+
```ruby
|
|
820
|
+
# @!attribute [rw] name
|
|
821
|
+
# @return [Object]
|
|
822
|
+
# @param [Object] value
|
|
823
|
+
#
|
|
824
|
+
# @!attribute [rw] email
|
|
825
|
+
# @return [Object]
|
|
826
|
+
# @param [Object] value
|
|
827
|
+
class User < Struct.new(:name, :email, keyword_init: true)
|
|
828
|
+
end
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
Docscribe preserves the original declaration style and does not rewrite one form into the other.
|
|
832
|
+
|
|
833
|
+
### Merge behavior
|
|
342
834
|
|
|
835
|
+
Struct member docs use the same attribute documentation pipeline as `attr_*` macros, which means they participate in the
|
|
836
|
+
normal safe/aggressive rewrite flow.
|
|
837
|
+
|
|
838
|
+
In safe mode, Docscribe can:
|
|
839
|
+
|
|
840
|
+
- insert full `@!attribute` docs when no doc-like block exists
|
|
841
|
+
- append missing struct member docs into an existing doc-like block
|
|
842
|
+
|
|
843
|
+
### Param tag style
|
|
844
|
+
|
|
845
|
+
Generated writer-style attribute docs respect `doc.param_tag_style`.
|
|
846
|
+
|
|
847
|
+
For example, with:
|
|
848
|
+
|
|
849
|
+
```yaml
|
|
343
850
|
doc:
|
|
344
|
-
|
|
851
|
+
param_tag_style: "type_name"
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
writer params are emitted as:
|
|
855
|
+
|
|
856
|
+
```ruby
|
|
857
|
+
# @param [Object] value
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
With:
|
|
861
|
+
|
|
862
|
+
```yaml
|
|
863
|
+
doc:
|
|
864
|
+
param_tag_style: "name_type"
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
they are emitted as:
|
|
868
|
+
|
|
869
|
+
```ruby
|
|
870
|
+
# @param value [Object]
|
|
871
|
+
```
|
|
872
|
+
|
|
873
|
+
### Create a starter config
|
|
345
874
|
|
|
346
|
-
|
|
347
|
-
instance:
|
|
348
|
-
public:
|
|
349
|
-
return_tag: true
|
|
350
|
-
default_message: "Public API. Please document purpose and params."
|
|
351
|
-
class:
|
|
352
|
-
private:
|
|
353
|
-
return_tag: false
|
|
875
|
+
Create `docscribe.yml` in the current directory:
|
|
354
876
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
nil_as_optional: true
|
|
358
|
-
treat_options_keyword_as_hash: true
|
|
877
|
+
```shell
|
|
878
|
+
docscribe init
|
|
359
879
|
```
|
|
360
880
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
881
|
+
Write to a custom path:
|
|
882
|
+
|
|
883
|
+
```shell
|
|
884
|
+
docscribe init --config config/docscribe.yml
|
|
885
|
+
```
|
|
366
886
|
|
|
367
|
-
|
|
887
|
+
Overwrite if it already exists:
|
|
368
888
|
|
|
369
|
-
```
|
|
370
|
-
docscribe
|
|
889
|
+
```shell
|
|
890
|
+
docscribe init --force
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
Print the template to stdout:
|
|
894
|
+
|
|
895
|
+
```shell
|
|
896
|
+
docscribe init --stdout
|
|
371
897
|
```
|
|
372
898
|
|
|
373
899
|
## CI integration
|
|
374
900
|
|
|
375
|
-
Fail the build if files would
|
|
901
|
+
Fail the build if files would need safe updates:
|
|
376
902
|
|
|
377
903
|
```yaml
|
|
378
904
|
- name: Check inline docs
|
|
379
|
-
run: docscribe
|
|
905
|
+
run: docscribe lib
|
|
380
906
|
```
|
|
381
907
|
|
|
382
|
-
|
|
908
|
+
Apply safe fixes before the test stage:
|
|
383
909
|
|
|
384
910
|
```yaml
|
|
385
|
-
- name:
|
|
386
|
-
run: docscribe
|
|
911
|
+
- name: Apply safe inline docs
|
|
912
|
+
run: docscribe -a lib
|
|
387
913
|
```
|
|
388
914
|
|
|
389
|
-
|
|
915
|
+
Aggressively rebuild docs:
|
|
390
916
|
|
|
391
917
|
```yaml
|
|
392
|
-
- name:
|
|
393
|
-
run: docscribe
|
|
918
|
+
- name: Rebuild inline docs
|
|
919
|
+
run: docscribe -A lib
|
|
394
920
|
```
|
|
395
921
|
|
|
396
922
|
## Comparison to YARD's parser
|
|
397
923
|
|
|
398
924
|
Docscribe and YARD solve different parts of the documentation problem:
|
|
399
925
|
|
|
400
|
-
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
- Semantics:
|
|
412
|
-
- Docscribe models Ruby visibility semantics precisely for inline usage (including `class << self`).
|
|
413
|
-
- YARD has rich semantics around tags and directives; it can leverage your inline comments (including those inserted
|
|
414
|
-
by Docscribe).
|
|
415
|
-
|
|
416
|
-
- Recommended workflow:
|
|
417
|
-
- Use Docscribe to seed and maintain inline docs with inferred tags/types.
|
|
418
|
-
- Optionally use YARD (dev-only) to render HTML from those comments:
|
|
419
|
-
```shell
|
|
420
|
-
yard doc -o docs
|
|
421
|
-
```
|
|
926
|
+
- Docscribe inserts/updates inline comments by rewriting source.
|
|
927
|
+
- YARD can generate HTML docs based on inline comments.
|
|
928
|
+
|
|
929
|
+
Recommended workflow:
|
|
930
|
+
|
|
931
|
+
- Use Docscribe to seed and maintain inline docs with inferred tags/types.
|
|
932
|
+
- Optionally use YARD (dev-only) to render HTML from those comments:
|
|
933
|
+
|
|
934
|
+
```shell
|
|
935
|
+
yard doc -o docs
|
|
936
|
+
```
|
|
422
937
|
|
|
423
938
|
## Limitations
|
|
424
939
|
|
|
425
|
-
-
|
|
426
|
-
|
|
427
|
-
- Type inference is heuristic. Complex flows and meta-programming will fall back to Object or best-effort types.
|
|
428
|
-
-
|
|
429
|
-
- Inline rewrite is textual; ensure a clean working tree before using `--write` or `--rewrite`.
|
|
940
|
+
- Safe mode only merges into existing **doc-like** comment blocks. Ordinary comments that are not recognized as
|
|
941
|
+
documentation are preserved and treated conservatively.
|
|
942
|
+
- Type inference is heuristic. Complex flows and meta-programming will fall back to `Object` or best-effort types.
|
|
943
|
+
- Aggressive mode (`-A`) replaces existing doc blocks and should be reviewed carefully.
|
|
430
944
|
|
|
431
945
|
## Roadmap
|
|
432
946
|
|
|
433
|
-
-
|
|
434
|
-
-
|
|
435
|
-
-
|
|
436
|
-
-
|
|
947
|
+
- Effective config dump;
|
|
948
|
+
- JSON output;
|
|
949
|
+
- Overload-aware signature selection;
|
|
950
|
+
- Manual `@!attribute` merge policy;
|
|
951
|
+
- Richer inference for common APIs;
|
|
952
|
+
- Editor integration.
|
|
437
953
|
|
|
438
954
|
## Contributing
|
|
439
955
|
|
|
440
|
-
Issues and PRs welcome. Please run:
|
|
441
|
-
|
|
442
956
|
```shell
|
|
443
957
|
bundle exec rspec
|
|
444
958
|
bundle exec rubocop
|
|
445
959
|
```
|
|
446
960
|
|
|
447
|
-
See CODE_OF_CONDUCT.md.
|
|
448
|
-
|
|
449
961
|
## License
|
|
450
962
|
|
|
451
963
|
MIT
|