docscribe 1.5.2 → 1.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 65ef814f594285faee2123170710fc06c47e3cf45471e79d4626fc2cb4885183
4
- data.tar.gz: '008dd20fd7a7c3a6c9254be9ac8158005a4a84779d070939a7abdad0476f6df9'
3
+ metadata.gz: 1016144165d119ade7719092f38974b29082a1bd86824864dd3a9b3412268771
4
+ data.tar.gz: ed2f6bbaf4e6f5892e0977a34c9aecb4924badc7e21ef25892d88bb4b0f8611a
5
5
  SHA512:
6
- metadata.gz: ff68cdf76163fc3a6e59192895b1b59a79116abb87f4921ea18d48b299a6b8f5e0be53ea090da01d089ed5b7cf954e77cfb78ca278012ced7fc97c39d76dfabc
7
- data.tar.gz: 9ed8f9e80ceea75d6072077cf08a6a9d2d1c6135dd99ea4478ffca41889169dddc6f329f8f10888d5d1fdeeb82dc84fa046c6a818eaae20fae32639773b5c8e9
6
+ metadata.gz: 7d1a11cef005ba87ef7fdf97d594ea699d638bc2a75dd62838ccec6f9260fca9b090e44a3176957584a30506f1159545354566a372c54e16382a2d384ae8248d
7
+ data.tar.gz: fd23695cdba7b7726e306ac2300665cb1f5eaf2764d2e19946df99fec6f7fee112408459fc774710305358a55d394413c4c8b3c663bd432514ffaf8f939d6dcf
data/README.md CHANGED
@@ -73,72 +73,74 @@ docscribe -A lib
73
73
 
74
74
  ## Contents
75
75
 
76
- * [Docscribe](#docscribe)
77
- * [Quick start](#quick-start)
78
- * [Contents](#contents)
79
- * [Installation](#installation)
80
- * [Architecture](#architecture)
81
- * [Data flow](#data-flow)
82
- * [CLI](#cli)
83
- * [Exit codes](#exit-codes)
84
- * [Options](#options)
85
- * [Examples](#examples)
86
- * [`docscribe sigs` — check RBS signature coverage](#docscribe-sigs--check-rbs-signature-coverage)
87
- * [`docscribe rbs` — generate RBS from YARD](#docscribe-rbs--generate-rbs-from-yard)
88
- * [`docscribe update_types` — two-pass type-aware documentation update](#docscribe-update_types--two-pass-type-aware-documentation-update)
89
- * [`docscribe check_for_comments` — find placeholder documentation](#docscribe-check_for_comments--find-placeholder-documentation)
90
- * [`docscribe server` — persistent daemon mode](#docscribe-server--persistent-daemon-mode)
91
- * [Update strategies](#update-strategies)
92
- * [Safe strategy](#safe-strategy)
93
- * [Aggressive strategy](#aggressive-strategy)
94
- * [Output markers](#output-markers)
95
- * [Tips & tricks](#tips--tricks)
96
- * [Parser backend (Parser gem vs Prism)](#parser-backend-parser-gem-vs-prism)
97
- * [External type integrations (optional)](#external-type-integrations-optional)
98
- * [RBS](#rbs)
99
- * [RBS collection auto-discovery](#rbs-collection-auto-discovery)
100
- * [Sorbet](#sorbet)
101
- * [Inline Sorbet example](#inline-sorbet-example)
102
- * [Sorbet RBI example](#sorbet-rbi-example)
103
- * [Sorbet comment placement](#sorbet-comment-placement)
104
- * [Generic type formatting](#generic-type-formatting)
105
- * [Notes and fallback behavior](#notes-and-fallback-behavior)
106
- * [Type inference](#type-inference)
107
- * [Rescue-aware returns and @raise](#rescue-aware-returns-and-raise)
108
- * [Visibility semantics](#visibility-semantics)
109
- * [API (library) usage](#api-library-usage)
110
- * [Plugin system](#plugin-system)
111
- * [TagPlugin](#tagplugin)
112
- * [CollectorPlugin](#collectorplugin)
113
- * [Plugin doc normalization (CollectorPlugin)](#plugin-doc-normalization-collectorplugin)
114
- * [`method_override` (structured patch)](#method_override-structured-patch)
115
- * [Registering plugins](#registering-plugins)
116
- * [Plugin priority](#plugin-priority)
117
- * [Idempotency](#idempotency)
118
- * [Plugin examples](#plugin-examples)
119
- * [Configuration](#configuration)
120
- * [Anonymous block parameters](#anonymous-block-parameters)
121
- * [Filtering](#filtering)
122
- * [`attr_*` example](#attr_-example)
123
- * [`Struct.new` examples](#structnew-examples)
124
- * [Constant-assigned struct](#constant-assigned-struct)
125
- * [Class-based struct](#class-based-struct)
126
- * [Merge behavior](#merge-behavior)
127
- * [Param tag style](#param-tag-style)
128
- * [Create a starter config](#create-a-starter-config)
129
- * [Generate a plugin skeleton](#generate-a-plugin-skeleton)
130
- * [Full configuration reference](#full-configuration-reference)
131
- * [CI integration](#ci-integration)
132
- * [Comparison to YARD's parser](#comparison-to-yards-parser)
133
- * [Limitations](#limitations)
134
- * [Roadmap](#roadmap)
135
- * [Editor Integration](#editor-integration)
136
- * [VS Code](#vs-code)
137
- * [RubyMine](#rubymine)
138
- * [Contributing](#contributing)
139
- * [Discussion & Community](#discussion--community)
140
- * [Logo Attribution](#logo-attribution)
141
- * [License](#license)
76
+ * [Quick start](#quick-start)
77
+ * [Contents](#contents)
78
+ * [Installation](#installation)
79
+ * [Architecture](#architecture)
80
+ * [Data flow](#data-flow)
81
+ * [CLI](#cli)
82
+ * [Exit codes](#exit-codes)
83
+ * [Options](#options)
84
+ * [Examples](#examples)
85
+ * [`docscribe sigs` — check RBS signature coverage](#docscribe-sigs--check-rbs-signature-coverage)
86
+ * [`docscribe rbs` — generate RBS from YARD](#docscribe-rbs--generate-rbs-from-yard)
87
+ * [`docscribe update_types` — two-pass type-aware documentation update](#docscribe-update_types--two-pass-type-aware-documentation-update)
88
+ * [`docscribe check_for_comments` — find placeholder documentation](#docscribe-check_for_comments--find-placeholder-documentation)
89
+ * [`docscribe init` — project scaffolding](#docscribe-init--project-scaffolding)
90
+ * [`docscribe config` — view resolved configuration](#docscribe-config--view-resolved-configuration)
91
+ * [`docscribe coverage` — documentation coverage report](#docscribe-coverage--documentation-coverage-report)
92
+ * [`docscribe server` — persistent daemon mode](#docscribe-server--persistent-daemon-mode)
93
+ * [Update strategies](#update-strategies)
94
+ * [Safe strategy](#safe-strategy)
95
+ * [Aggressive strategy](#aggressive-strategy)
96
+ * [Output markers](#output-markers)
97
+ * [Tips & tricks](#tips--tricks)
98
+ * [Parser backend (Parser gem vs Prism)](#parser-backend-parser-gem-vs-prism)
99
+ * [External type integrations (optional)](#external-type-integrations-optional)
100
+ * [RBS](#rbs)
101
+ * [RBS collection auto-discovery](#rbs-collection-auto-discovery)
102
+ * [Sorbet](#sorbet)
103
+ * [Inline Sorbet example](#inline-sorbet-example)
104
+ * [Sorbet RBI example](#sorbet-rbi-example)
105
+ * [Sorbet comment placement](#sorbet-comment-placement)
106
+ * [Generic type formatting](#generic-type-formatting)
107
+ * [Notes and fallback behavior](#notes-and-fallback-behavior)
108
+ * [Type inference](#type-inference)
109
+ * [Rescue-aware returns and @raise](#rescue-aware-returns-and-raise)
110
+ * [Visibility semantics](#visibility-semantics)
111
+ * [API (library) usage](#api-library-usage)
112
+ * [Plugin system](#plugin-system)
113
+ * [TagPlugin](#tagplugin)
114
+ * [CollectorPlugin](#collectorplugin)
115
+ * [Plugin doc normalization (CollectorPlugin)](#plugin-doc-normalization-collectorplugin)
116
+ * [`method_override` (structured patch)](#method_override-structured-patch)
117
+ * [Registering plugins](#registering-plugins)
118
+ * [Plugin priority](#plugin-priority)
119
+ * [Idempotency](#idempotency)
120
+ * [Plugin examples](#plugin-examples)
121
+ * [Configuration](#configuration)
122
+ * [Anonymous block parameters](#anonymous-block-parameters)
123
+ * [Filtering](#filtering)
124
+ * [`attr_*` example](#attr_-example)
125
+ * [`Struct.new` examples](#structnew-examples)
126
+ * [Constant-assigned struct](#constant-assigned-struct)
127
+ * [Class-based struct](#class-based-struct)
128
+ * [Merge behavior](#merge-behavior)
129
+ * [Param tag style](#param-tag-style)
130
+ * [Create a starter config](#create-a-starter-config)
131
+ * [Generate a plugin skeleton](#generate-a-plugin-skeleton)
132
+ * [Full configuration reference](#full-configuration-reference)
133
+ * [CI integration](#ci-integration)
134
+ * [Comparison to YARD's parser](#comparison-to-yards-parser)
135
+ * [Limitations](#limitations)
136
+ * [Roadmap](#roadmap)
137
+ * [Editor Integration](#editor-integration)
138
+ * [VS Code](#vs-code)
139
+ * [RubyMine](#rubymine)
140
+ * [Contributing](#contributing)
141
+ * [Discussion & Community](#discussion--community)
142
+ * [Logo Attribution](#logo-attribution)
143
+ * [License](#license)
142
144
 
143
145
  ## Installation
144
146
 
@@ -411,6 +413,9 @@ If you pass no files and don't use `--stdin`, Docscribe processes the current di
411
413
  - `--progress`
412
414
  Show progress (`[N/total] path/to/file.rb`) on stderr as each file is processed.
413
415
 
416
+ - `DOCSCRIBE_THREADS` (env var)
417
+ Number of parallel worker threads (default: 4). Set to `1` for sequential processing.
418
+
414
419
  - `--quiet` (`-q`)
415
420
  Only show status, no details (suppresses change reasons).
416
421
  Overrides the default detailed output.
@@ -645,6 +650,63 @@ Exit code `0` if no placeholders found, `1` if any are detected.
645
650
 
646
651
  - `-h`, `--help` — show help.
647
652
 
653
+ ### `docscribe init` — project scaffolding
654
+
655
+ `docscribe init` creates a default `docscribe.yml` config file in the current directory. It asks interactive questions
656
+ about your project and writes a tailored configuration.
657
+
658
+ ```shell
659
+ # Create docscribe.yml interactively
660
+ docscribe init
661
+
662
+ # Create with default settings (non-interactive)
663
+ docscribe init --default
664
+ ```
665
+
666
+ **Flags:**
667
+
668
+ - `--pre-commit` — generate and install a Git pre-commit hook that checks documentation on staged `.rb` files using
669
+ `docscribe --verbose`. The hook exits with a warning if staged files lack documentation.
670
+ - `--pre-commit --uninstall` — remove the pre-commit hook.
671
+ - `--pre-commit --dry-run` — preview the hook script without installing.
672
+ - `--default` — skip interactive prompts, write default config.
673
+ - `-h`, `--help` — show help.
674
+
675
+ ### `docscribe config` — view resolved configuration
676
+
677
+ `docscribe config` prints the fully resolved configuration (defaults + file + CLI overrides) as YAML.
678
+
679
+ ```shell
680
+ # Print resolved config
681
+ docscribe config
682
+
683
+ # Use a specific config file
684
+ docscribe config --config path/to/docscribe.yml
685
+ ```
686
+
687
+ **Flags:**
688
+
689
+ - `--config PATH` — path to config file.
690
+ - `-h`, `--help` — show help.
691
+
692
+ ### `docscribe coverage` — documentation coverage report
693
+
694
+ `docscribe coverage` scans Ruby files and reports the percentage of documented methods, parameters, and return types.
695
+
696
+ ```shell
697
+ # Generate coverage report (text table)
698
+ docscribe coverage lib
699
+
700
+ # JSON output for tooling
701
+ docscribe coverage --format json lib
702
+ ```
703
+
704
+ **Flags:**
705
+
706
+ - `--format FORMAT` — output format: `text` (default, human-readable table) or `json` (machine-readable).
707
+ - `--config PATH` — path to config file.
708
+ - `-h`, `--help` — show help.
709
+
648
710
  ### `docscribe server` — persistent daemon mode
649
711
 
650
712
  > [!NOTE]
@@ -743,23 +805,23 @@ The daemon speaks JSON-RPC 2.0 over Unix socket. Each request is a JSON line, ea
743
805
 
744
806
  Methods:
745
807
 
746
- | Method | Parameters | Result |
747
- |--------|-----------|--------|
748
- | `check` | `file` (string), `strategy` ("safe"/"aggressive"), `cli_overrides` (hash, optional) | `status`, `changed`, `changes` |
749
- | `fix` | same as `check` | `status`, `changed`, `changes` |
750
- | `check_batch` | `files` (array of strings), `strategy`, `cli_overrides`, `timeout` (int, optional) | array of per-file results |
751
- | `ping` | — | `version`, `pid`, `socket_path`, `started_at`, `uptime` |
752
- | `shutdown` | — | `status` |
808
+ | Method | Parameters | Result |
809
+ |---------------|-------------------------------------------------------------------------------------|---------------------------------------------------------|
810
+ | `check` | `file` (string), `strategy` ("safe"/"aggressive"), `cli_overrides` (hash, optional) | `status`, `changed`, `changes` |
811
+ | `fix` | same as `check` | `status`, `changed`, `changes` |
812
+ | `check_batch` | `files` (array of strings), `strategy`, `cli_overrides`, `timeout` (int, optional) | array of per-file results |
813
+ | `ping` | — | `version`, `pid`, `socket_path`, `started_at`, `uptime` |
814
+ | `shutdown` | — | `status` |
753
815
 
754
816
  Error codes (standardized for IDE plugin integration):
755
817
 
756
- | Code | Meaning | `error.data` fields |
757
- |------|---------|-------------------|
758
- | `-32000` | Gem/dependency not found | `gem` |
759
- | `-32001` | Syntax error in analyzed file | `file`, `line`, `detail` |
760
- | `-32002` | Config load failure | — |
761
- | `-32010` | Timeout | `timeout`, `file` |
762
- | `-32099` | Internal unhandled error | `backtrace` (first 5 lines) |
818
+ | Code | Meaning | `error.data` fields |
819
+ |----------|-------------------------------|-----------------------------|
820
+ | `-32000` | Gem/dependency not found | `gem` |
821
+ | `-32001` | Syntax error in analyzed file | `file`, `line`, `detail` |
822
+ | `-32002` | Config load failure | — |
823
+ | `-32010` | Timeout | `timeout`, `file` |
824
+ | `-32099` | Internal unhandled error | `backtrace` (first 5 lines) |
763
825
 
764
826
  **Socket path derivation:**
765
827
 
@@ -798,6 +860,17 @@ Safe strategy:
798
860
 
799
861
  This is the recommended day-to-day mode.
800
862
 
863
+ **`@!attribute` merge policy in safe mode:**
864
+
865
+ When a method already has a YARD `@!attribute` doc block (e.g. `# @!attribute [rw] name`), safe mode does not
866
+ overwrite it. Instead it merges only the missing parts:
867
+
868
+ - If the attribute has `[r]` or `[rw]` access and no `@return` tag exists — adds `@return [Type]`.
869
+ - If the attribute has `[w]` or `[rw]` access and no `@param` tag exists — adds `@param value [Type]`.
870
+ - If some attrs from the `attr_*` call are present in the doc block but others are missing — adds only the missing ones.
871
+
872
+ This preserves hand-written annotations while ensuring complete documentation.
873
+
801
874
  ### Aggressive strategy
802
875
 
803
876
  Used by:
@@ -1929,16 +2002,10 @@ yard doc -o docs
1929
2002
 
1930
2003
  ## Roadmap
1931
2004
 
1932
- - Method behavior inference from AST;
2005
+ - Overload-aware signature selection;
1933
2006
  - Deeper YARD integration — parse `.c` source comments and generate docs for C-extensions;
1934
2007
  - Custom parser plugins — support non-Ruby languages (Crystal, etc.) via the plugin system;
1935
- - Effective config dump;
1936
- - Overload-aware signature selection;
1937
- - Manual `@!attribute` merge policy;
1938
- - Richer inference for common APIs;
1939
- - Documentation coverage report — percentage of documented methods, params, returns;
1940
- - Pre-commit hook auto-install (`docscribe init --pre-commit`);
1941
- - Parallel processing for large codebases.
2008
+ - Richer inference for common APIs.
1942
2009
 
1943
2010
  ## Editor Integration
1944
2011
 
data/exe/docscribe-client CHANGED
@@ -148,6 +148,8 @@ when :status
148
148
  end
149
149
  puts JSON.generate(alive ? { status: 'running', socket: sock } : { status: 'not_running' })
150
150
  else
151
- warn "Usage: #{$PROGRAM_NAME} --check <file> | --fix <file> | --check-batch <files> | --shutdown | --status | --ping | --socket-path | --info | --ensure"
151
+ warn "Usage: #{$PROGRAM_NAME} --check <file> | --fix <file> " \
152
+ '| --check-batch <files> | --shutdown | --status | --ping ' \
153
+ '| --socket-path | --info | --ensure'
152
154
  exit 1
153
155
  end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'optparse'
4
+ require 'yaml'
5
+ require 'docscribe/config'
6
+ require 'docscribe/cli/config_builder'
7
+
8
+ module Docscribe
9
+ module CLI
10
+ # Print the fully resolved configuration as YAML.
11
+ module ConfigDump
12
+ BANNER = <<~TEXT
13
+ Usage: docscribe config [options]
14
+
15
+ Print the fully resolved configuration as YAML.
16
+
17
+ Options:
18
+ TEXT
19
+
20
+ class << self
21
+ # @param [Array<String>] argv
22
+ # @return [Integer]
23
+ def run(argv)
24
+ opts = parse_options(argv)
25
+ return 0 if opts[:help]
26
+
27
+ conf = Docscribe::Config.load(opts[:config])
28
+ conf = Docscribe::CLI::ConfigBuilder.build(conf, parse_cli_overrides(argv))
29
+
30
+ puts conf.to_h.to_yaml
31
+ 0
32
+ end
33
+
34
+ private
35
+
36
+ # @private
37
+ # @param [Array<String>] argv
38
+ # @return [Hash<Symbol, Object>]
39
+ def parse_options(argv)
40
+ opts = { config: nil }
41
+ build_parser(opts).parse!(argv)
42
+ opts
43
+ end
44
+
45
+ # @private
46
+ # @param [Hash<Symbol, Object>] opts
47
+ # @return [OptionParser]
48
+ def build_parser(opts)
49
+ OptionParser.new do |o|
50
+ o.banner = BANNER
51
+ o.on('--config PATH', 'Path to config file') { |v| opts[:config] = v }
52
+ o.on('-h', '--help', 'Show help') do
53
+ opts[:help] = true
54
+ puts o
55
+ end
56
+ end
57
+ end
58
+
59
+ # @private
60
+ # @param [Array<String>] argv
61
+ # @return [Hash<Symbol, Object>]
62
+ def parse_cli_overrides(argv)
63
+ opts = Docscribe::CLI::Options.parse!(argv)
64
+ opts.slice(:rbs, :rbs_collection, :sorbet, :sig_dirs, :rbi_dirs, :include, :exclude, :include_file,
65
+ :exclude_file)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end