docscribe 1.4.2 → 1.5.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 +465 -130
- data/lib/docscribe/cli/check_for_comments.rb +183 -0
- data/lib/docscribe/cli/config_builder.rb +107 -53
- data/lib/docscribe/cli/formatters/json.rb +294 -0
- data/lib/docscribe/cli/formatters/sarif.rb +235 -0
- data/lib/docscribe/cli/formatters/text.rb +208 -0
- data/lib/docscribe/cli/formatters.rb +26 -0
- data/lib/docscribe/cli/generate.rb +45 -45
- data/lib/docscribe/cli/init.rb +14 -6
- data/lib/docscribe/cli/options.rb +190 -88
- data/lib/docscribe/cli/rbs_gen.rb +529 -0
- data/lib/docscribe/cli/run.rb +210 -152
- data/lib/docscribe/cli/sigs.rb +366 -0
- data/lib/docscribe/cli/update_types.rb +103 -0
- data/lib/docscribe/cli.rb +21 -13
- data/lib/docscribe/config/defaults.rb +5 -1
- data/lib/docscribe/config/emit.rb +17 -0
- data/lib/docscribe/config/filtering.rb +18 -25
- data/lib/docscribe/config/loader.rb +15 -11
- data/lib/docscribe/config/plugin.rb +1 -1
- data/lib/docscribe/config/rbs.rb +41 -9
- data/lib/docscribe/config/sorbet.rb +9 -12
- data/lib/docscribe/config/sorting.rb +1 -1
- data/lib/docscribe/config/template.rb +9 -1
- data/lib/docscribe/config/utils.rb +11 -9
- data/lib/docscribe/config.rb +2 -4
- data/lib/docscribe/infer/ast_walk.rb +1 -1
- data/lib/docscribe/infer/literals.rb +6 -11
- data/lib/docscribe/infer/names.rb +2 -3
- data/lib/docscribe/infer/params.rb +15 -17
- data/lib/docscribe/infer/raises.rb +3 -5
- data/lib/docscribe/infer/returns.rb +542 -140
- data/lib/docscribe/infer.rb +22 -23
- data/lib/docscribe/inline_rewriter/collector.rb +159 -164
- data/lib/docscribe/inline_rewriter/doc_block.rb +145 -115
- data/lib/docscribe/inline_rewriter/doc_builder.rb +1026 -723
- data/lib/docscribe/inline_rewriter/source_helpers.rb +49 -49
- data/lib/docscribe/inline_rewriter/tag_sorter.rb +82 -85
- data/lib/docscribe/inline_rewriter.rb +495 -492
- data/lib/docscribe/parsing.rb +29 -10
- data/lib/docscribe/plugin/base/collector_plugin.rb +2 -1
- data/lib/docscribe/plugin/base/tag_plugin.rb +0 -1
- data/lib/docscribe/plugin/context.rb +28 -18
- data/lib/docscribe/plugin/registry.rb +26 -27
- data/lib/docscribe/plugin/tag.rb +9 -14
- data/lib/docscribe/plugin.rb +17 -16
- data/lib/docscribe/types/provider_chain.rb +4 -2
- data/lib/docscribe/types/rbs/collection_loader.rb +2 -2
- data/lib/docscribe/types/rbs/provider.rb +60 -44
- data/lib/docscribe/types/rbs/type_formatter.rb +224 -83
- data/lib/docscribe/types/signature.rb +22 -42
- data/lib/docscribe/types/sorbet/base_provider.rb +24 -19
- data/lib/docscribe/types/sorbet/rbi_provider.rb +3 -3
- data/lib/docscribe/types/sorbet/source_provider.rb +3 -2
- data/lib/docscribe/types/yard/formatter.rb +100 -0
- data/lib/docscribe/types/yard/parser.rb +240 -0
- data/lib/docscribe/types/yard/types.rb +52 -0
- data/lib/docscribe/version.rb +1 -1
- metadata +33 -1
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Docscribe
|
|
4
|
+
module CLI
|
|
5
|
+
module Formatters
|
|
6
|
+
# Text output formatter preserving the original CLI output format.
|
|
7
|
+
class Text
|
|
8
|
+
# Format and print check summary.
|
|
9
|
+
#
|
|
10
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
11
|
+
# @param [Docscribe::CLI::Formatters::opts] options runtime options hash
|
|
12
|
+
# @return [void]
|
|
13
|
+
def format_check_summary(state:, options:)
|
|
14
|
+
puts
|
|
15
|
+
format_fail_paths(state, options)
|
|
16
|
+
format_check_status_line(state)
|
|
17
|
+
format_type_mismatch_paths(state, options)
|
|
18
|
+
format_error_paths(state)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Format and print write summary.
|
|
22
|
+
#
|
|
23
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
24
|
+
# @param [Docscribe::CLI::Formatters::opts] options runtime options hash
|
|
25
|
+
# @return [void]
|
|
26
|
+
def format_write_summary(state:, options:)
|
|
27
|
+
puts
|
|
28
|
+
puts "Docscribe: updated #{state[:corrected]} file(s)" if state[:corrected].positive?
|
|
29
|
+
format_corrected_paths(state, options)
|
|
30
|
+
|
|
31
|
+
return unless state[:had_errors]
|
|
32
|
+
|
|
33
|
+
warn "Docscribe: #{state[:error_paths].size} file(s) had errors"
|
|
34
|
+
format_error_paths(state)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Print files needing updates.
|
|
38
|
+
#
|
|
39
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
40
|
+
# @param [Docscribe::CLI::Formatters::opts] options runtime options hash
|
|
41
|
+
# @return [void]
|
|
42
|
+
def format_fail_paths(state, options)
|
|
43
|
+
state[:fail_paths].each do |p|
|
|
44
|
+
puts "Would update: #{p}"
|
|
45
|
+
|
|
46
|
+
next if options[:verbose] || options[:quiet]
|
|
47
|
+
|
|
48
|
+
Array(state[:fail_changes][p]).each do |change|
|
|
49
|
+
puts " - #{format_change_reason(change)}"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Print check status line.
|
|
55
|
+
#
|
|
56
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
57
|
+
# @return [void]
|
|
58
|
+
def format_check_status_line(state)
|
|
59
|
+
checked_error = state[:error_paths].size
|
|
60
|
+
type_mismatch_count = state[:type_mismatch_paths].size
|
|
61
|
+
|
|
62
|
+
if all_fine?(state, checked_error, type_mismatch_count)
|
|
63
|
+
puts "Docscribe: OK (#{state[:checked_ok]} files checked)"
|
|
64
|
+
elsif mismatch_only?(state, checked_error)
|
|
65
|
+
puts "Docscribe: OK (#{state[:checked_ok]} files checked, #{type_mismatch_count} with type mismatches)"
|
|
66
|
+
else
|
|
67
|
+
puts failure_line(state, type_mismatch_count, checked_error)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Print type mismatch warnings.
|
|
72
|
+
#
|
|
73
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
74
|
+
# @param [Docscribe::CLI::Formatters::opts] options runtime options hash
|
|
75
|
+
# @return [void]
|
|
76
|
+
def format_type_mismatch_paths(state, options)
|
|
77
|
+
return if options[:quiet]
|
|
78
|
+
return unless options[:verbose] || options[:explain]
|
|
79
|
+
|
|
80
|
+
state[:type_mismatch_paths].each do |p|
|
|
81
|
+
warn "Type mismatches: #{p}"
|
|
82
|
+
Array(state[:type_mismatch_changes][p]).each do |change|
|
|
83
|
+
warn " - #{format_change_reason(change)}"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Print updated file paths.
|
|
89
|
+
#
|
|
90
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
91
|
+
# @param [Docscribe::CLI::Formatters::opts] options runtime options hash
|
|
92
|
+
# @return [void]
|
|
93
|
+
def format_corrected_paths(state, options)
|
|
94
|
+
state[:corrected_paths].each do |p|
|
|
95
|
+
puts "Updated: #{p}"
|
|
96
|
+
|
|
97
|
+
next if options[:verbose] || options[:quiet]
|
|
98
|
+
|
|
99
|
+
Array(state[:corrected_changes][p]).each do |change|
|
|
100
|
+
puts " - #{format_change_reason(change)}"
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Print error file messages.
|
|
106
|
+
#
|
|
107
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
108
|
+
# @return [void]
|
|
109
|
+
def format_error_paths(state)
|
|
110
|
+
return if state[:error_paths].empty?
|
|
111
|
+
|
|
112
|
+
warn ''
|
|
113
|
+
state[:error_paths].each do |p|
|
|
114
|
+
warn "Error processing: #{p}"
|
|
115
|
+
warn " #{state[:error_messages][p]}" if state[:error_messages][p]
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
private
|
|
120
|
+
|
|
121
|
+
# Check if all files passed.
|
|
122
|
+
#
|
|
123
|
+
# @private
|
|
124
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
125
|
+
# @param [Integer] checked_error count of error files
|
|
126
|
+
# @param [Integer] type_mismatch_count count of type mismatches
|
|
127
|
+
# @return [Boolean]
|
|
128
|
+
def all_fine?(state, checked_error, type_mismatch_count)
|
|
129
|
+
state[:checked_fail].zero? && checked_error.zero? && type_mismatch_count.zero?
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Check only type mismatches.
|
|
133
|
+
#
|
|
134
|
+
# @private
|
|
135
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
136
|
+
# @param [Integer] checked_error count of error files
|
|
137
|
+
# @return [Boolean]
|
|
138
|
+
def mismatch_only?(state, checked_error)
|
|
139
|
+
state[:checked_fail].zero? && checked_error.zero?
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Build failure status line.
|
|
143
|
+
#
|
|
144
|
+
# @private
|
|
145
|
+
# @param [Docscribe::CLI::Formatters::state] state formatter state hash
|
|
146
|
+
# @param [Integer] type_mismatch_count count of type mismatches
|
|
147
|
+
# @param [Integer] checked_error count of error files
|
|
148
|
+
# @return [String]
|
|
149
|
+
def failure_line(state, type_mismatch_count, checked_error)
|
|
150
|
+
parts = ["#{state[:checked_fail]} need updates"]
|
|
151
|
+
parts << "#{type_mismatch_count} type mismatches" if type_mismatch_count.positive?
|
|
152
|
+
parts << "#{checked_error} errors"
|
|
153
|
+
parts << "#{state[:checked_ok]} ok"
|
|
154
|
+
"Docscribe: FAILED (#{parts.join(', ')})"
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Format change reason string.
|
|
158
|
+
#
|
|
159
|
+
# @private
|
|
160
|
+
# @param [Docscribe::CLI::Formatters::change] change change info hash
|
|
161
|
+
# @return [String]
|
|
162
|
+
def format_change_reason(change)
|
|
163
|
+
line = change_line_suffix(change)
|
|
164
|
+
method = change_method_suffix(change)
|
|
165
|
+
|
|
166
|
+
return "unsorted tags#{line}" if change[:type] == :unsorted_tags
|
|
167
|
+
return "#{change[:message]}#{method}#{line}" if direct_message_change?(change)
|
|
168
|
+
|
|
169
|
+
"#{change[:message] || change[:type].to_s.tr('_', ' ')}#{method}#{line}"
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Build change line suffix.
|
|
173
|
+
#
|
|
174
|
+
# @private
|
|
175
|
+
# @param [Docscribe::CLI::Formatters::change] change change info hash
|
|
176
|
+
# @return [String]
|
|
177
|
+
def change_line_suffix(change)
|
|
178
|
+
change[:line] ? " at line #{change[:line]}" : ''
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Build change method suffix.
|
|
182
|
+
#
|
|
183
|
+
# @private
|
|
184
|
+
# @param [Docscribe::CLI::Formatters::change] change change info hash
|
|
185
|
+
# @return [String]
|
|
186
|
+
def change_method_suffix(change)
|
|
187
|
+
change[:method] ? " for #{change[:method]}" : ''
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Check direct message type.
|
|
191
|
+
#
|
|
192
|
+
# @private
|
|
193
|
+
# @param [Docscribe::CLI::Formatters::change] change change info hash
|
|
194
|
+
# @return [Boolean]
|
|
195
|
+
def direct_message_change?(change)
|
|
196
|
+
%i[
|
|
197
|
+
missing_param
|
|
198
|
+
missing_return
|
|
199
|
+
missing_raise
|
|
200
|
+
missing_visibility
|
|
201
|
+
missing_module_function_note
|
|
202
|
+
insert_full_doc_block
|
|
203
|
+
].include?(change[:type])
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Docscribe
|
|
4
|
+
module CLI
|
|
5
|
+
# Factory for output formatters.
|
|
6
|
+
module Formatters
|
|
7
|
+
# Select formatter by format type.
|
|
8
|
+
#
|
|
9
|
+
# @param [Docscribe::CLI::Formatters::format] format output format symbol
|
|
10
|
+
# @raise [ArgumentError]
|
|
11
|
+
# @return [Docscribe::CLI::Formatters::Text, Docscribe::CLI::Formatters::Json, Docscribe::CLI::Formatters::Sarif]
|
|
12
|
+
def self.for(format)
|
|
13
|
+
case format
|
|
14
|
+
when :text then Text.new
|
|
15
|
+
when :json then Json.new
|
|
16
|
+
when :sarif then Sarif.new
|
|
17
|
+
else raise ArgumentError, "Unknown format: #{format}"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
require_relative 'formatters/text'
|
|
25
|
+
require_relative 'formatters/json'
|
|
26
|
+
require_relative 'formatters/sarif'
|
|
@@ -34,8 +34,7 @@ module Docscribe
|
|
|
34
34
|
class << self
|
|
35
35
|
# Run the `generate` subcommand.
|
|
36
36
|
#
|
|
37
|
-
# @param [Array<String>] argv
|
|
38
|
-
# @raise [OptionParser::InvalidOption]
|
|
37
|
+
# @param [Array<String>] argv command line arguments
|
|
39
38
|
# @return [Integer] exit code
|
|
40
39
|
def run(argv)
|
|
41
40
|
opts, parser = parse_generate_options(argv)
|
|
@@ -54,9 +53,9 @@ module Docscribe
|
|
|
54
53
|
# Parse options for the generate subcommand.
|
|
55
54
|
#
|
|
56
55
|
# @private
|
|
57
|
-
# @param [Array<String>] argv
|
|
56
|
+
# @param [Array<String>] argv command line arguments
|
|
58
57
|
# @raise [OptionParser::InvalidOption]
|
|
59
|
-
# @return [
|
|
58
|
+
# @return [(Hash<Symbol, Object>, OptionParser)]
|
|
60
59
|
def parse_generate_options(argv)
|
|
61
60
|
opts = { output: nil, stdout: false, help: false }
|
|
62
61
|
parser = build_option_parser(opts)
|
|
@@ -74,8 +73,8 @@ module Docscribe
|
|
|
74
73
|
# Extract plugin_type and class_name from remaining argv.
|
|
75
74
|
#
|
|
76
75
|
# @private
|
|
77
|
-
# @param [Array<String>] argv
|
|
78
|
-
# @return [
|
|
76
|
+
# @param [Array<String>] argv command line arguments
|
|
77
|
+
# @return [(String?, String?)]
|
|
79
78
|
def extract_generate_args(argv)
|
|
80
79
|
[argv.shift, argv.shift]
|
|
81
80
|
end
|
|
@@ -83,9 +82,9 @@ module Docscribe
|
|
|
83
82
|
# Validate generate arguments and return exit code on failure.
|
|
84
83
|
#
|
|
85
84
|
# @private
|
|
86
|
-
# @param [String
|
|
87
|
-
# @param [String
|
|
88
|
-
# @param [OptionParser] parser
|
|
85
|
+
# @param [String?] plugin_type 'tag' or 'collector'
|
|
86
|
+
# @param [String?] class_name CamelCase plugin class name
|
|
87
|
+
# @param [OptionParser] parser option parser instance
|
|
89
88
|
# @return [Integer, nil] exit code or nil if valid
|
|
90
89
|
def validate_generate_args(plugin_type, class_name, parser)
|
|
91
90
|
return 1 unless args_provided?(plugin_type, class_name, parser)
|
|
@@ -98,9 +97,9 @@ module Docscribe
|
|
|
98
97
|
# Render plugin boilerplate for the given type and class name.
|
|
99
98
|
#
|
|
100
99
|
# @private
|
|
101
|
-
# @param [String] plugin_type 'tag' or 'collector'
|
|
102
|
-
# @param [String] class_name
|
|
103
|
-
# @return [String]
|
|
100
|
+
# @param [String?] plugin_type 'tag' or 'collector'
|
|
101
|
+
# @param [String?] class_name CamelCase plugin class name
|
|
102
|
+
# @return [String?]
|
|
104
103
|
def render(plugin_type, class_name)
|
|
105
104
|
case plugin_type
|
|
106
105
|
when 'tag' then tag_template(class_name)
|
|
@@ -111,7 +110,7 @@ module Docscribe
|
|
|
111
110
|
# Template for a TagPlugin.
|
|
112
111
|
#
|
|
113
112
|
# @private
|
|
114
|
-
# @param [String] class_name
|
|
113
|
+
# @param [String?] class_name CamelCase plugin class name
|
|
115
114
|
# @return [String]
|
|
116
115
|
def tag_template(class_name)
|
|
117
116
|
<<~RUBY
|
|
@@ -169,7 +168,7 @@ module Docscribe
|
|
|
169
168
|
# Template for a CollectorPlugin.
|
|
170
169
|
#
|
|
171
170
|
# @private
|
|
172
|
-
# @param [String] class_name
|
|
171
|
+
# @param [String?] class_name CamelCase plugin class name
|
|
173
172
|
# @return [String]
|
|
174
173
|
def collector_template(class_name)
|
|
175
174
|
<<~RUBY
|
|
@@ -237,10 +236,10 @@ module Docscribe
|
|
|
237
236
|
# Write generated plugin to a file or print to STDOUT based on options.
|
|
238
237
|
#
|
|
239
238
|
# @private
|
|
240
|
-
# @param [String] content generated plugin source code
|
|
241
|
-
# @param [String] plugin_type 'tag' or 'collector'
|
|
242
|
-
# @param [String] class_name CamelCase plugin class name
|
|
243
|
-
# @param [Hash] opts parsed options hash
|
|
239
|
+
# @param [String?] content generated plugin source code
|
|
240
|
+
# @param [String?] plugin_type 'tag' or 'collector'
|
|
241
|
+
# @param [String?] class_name CamelCase plugin class name
|
|
242
|
+
# @param [Hash<Symbol, Object>] opts parsed options hash
|
|
244
243
|
# @return [Integer] exit code
|
|
245
244
|
def dispatch_output(content, plugin_type, class_name, opts)
|
|
246
245
|
if opts[:stdout]
|
|
@@ -254,10 +253,10 @@ module Docscribe
|
|
|
254
253
|
# Write the generated content to a file.
|
|
255
254
|
#
|
|
256
255
|
# @private
|
|
257
|
-
# @param [String] content
|
|
258
|
-
# @param [String] plugin_type
|
|
259
|
-
# @param [String] class_name
|
|
260
|
-
# @param [String] output_dir
|
|
256
|
+
# @param [String?] content file content to write
|
|
257
|
+
# @param [String?] plugin_type 'tag' or 'collector'
|
|
258
|
+
# @param [String?] class_name CamelCase plugin class name
|
|
259
|
+
# @param [String?] output_dir output directory path
|
|
261
260
|
# @return [Integer] exit code
|
|
262
261
|
def write_plugin(content, plugin_type:, class_name:, output_dir:)
|
|
263
262
|
path = plugin_path(class_name, output_dir)
|
|
@@ -272,7 +271,7 @@ module Docscribe
|
|
|
272
271
|
# Build the OptionParser for the generate subcommand.
|
|
273
272
|
#
|
|
274
273
|
# @private
|
|
275
|
-
# @param [Hash] opts mutable parsed options hash
|
|
274
|
+
# @param [Hash<Symbol, Object>] opts mutable parsed options hash
|
|
276
275
|
# @return [OptionParser]
|
|
277
276
|
def build_option_parser(opts)
|
|
278
277
|
OptionParser.new do |opt|
|
|
@@ -302,8 +301,8 @@ module Docscribe
|
|
|
302
301
|
# Register the --output option on the OptionParser.
|
|
303
302
|
#
|
|
304
303
|
# @private
|
|
305
|
-
# @param [OptionParser] opt
|
|
306
|
-
# @param [Hash] opts mutable parsed options hash
|
|
304
|
+
# @param [OptionParser] opt option parser instance
|
|
305
|
+
# @param [Hash<Symbol, Object>] opts mutable parsed options hash
|
|
307
306
|
# @return [void]
|
|
308
307
|
def register_output_option(opt, opts)
|
|
309
308
|
opt.on('--output DIR', 'Directory to write the plugin file (default: .)') { |v| opts[:output] = v }
|
|
@@ -312,8 +311,8 @@ module Docscribe
|
|
|
312
311
|
# Register the --stdout option on the OptionParser.
|
|
313
312
|
#
|
|
314
313
|
# @private
|
|
315
|
-
# @param [OptionParser] opt
|
|
316
|
-
# @param [Hash] opts mutable parsed options hash
|
|
314
|
+
# @param [OptionParser] opt option parser instance
|
|
315
|
+
# @param [Hash<Symbol, Object>] opts mutable parsed options hash
|
|
317
316
|
# @return [void]
|
|
318
317
|
def register_stdout_option(opt, opts)
|
|
319
318
|
opt.on('--stdout', 'Print the generated plugin to STDOUT instead of writing a file') { opts[:stdout] = true }
|
|
@@ -322,11 +321,12 @@ module Docscribe
|
|
|
322
321
|
# Register the -h/--help option on the OptionParser.
|
|
323
322
|
#
|
|
324
323
|
# @private
|
|
325
|
-
# @param [OptionParser] opt
|
|
326
|
-
# @param [Hash] opts mutable parsed options hash
|
|
324
|
+
# @param [OptionParser] opt option parser instance
|
|
325
|
+
# @param [Hash<Symbol, Object>] opts mutable parsed options hash
|
|
327
326
|
# @return [void]
|
|
328
327
|
def register_help_option(opt, opts)
|
|
329
328
|
opt.on('-h', '--help', 'Show this help') do
|
|
329
|
+
puts opt
|
|
330
330
|
opts[:help] = true
|
|
331
331
|
end
|
|
332
332
|
end
|
|
@@ -334,9 +334,9 @@ module Docscribe
|
|
|
334
334
|
# Validate that both plugin_type and class_name arguments were provided.
|
|
335
335
|
#
|
|
336
336
|
# @private
|
|
337
|
-
# @param [String
|
|
338
|
-
# @param [String
|
|
339
|
-
# @param [OptionParser] parser
|
|
337
|
+
# @param [String?] plugin_type plugin type argument
|
|
338
|
+
# @param [String?] class_name plugin class name argument
|
|
339
|
+
# @param [OptionParser] parser option parser instance
|
|
340
340
|
# @return [Boolean]
|
|
341
341
|
def args_provided?(plugin_type, class_name, parser)
|
|
342
342
|
return true if plugin_type && class_name
|
|
@@ -349,7 +349,7 @@ module Docscribe
|
|
|
349
349
|
# Validate that the plugin type is one of the recognized types.
|
|
350
350
|
#
|
|
351
351
|
# @private
|
|
352
|
-
# @param [String] plugin_type plugin type to validate
|
|
352
|
+
# @param [String?] plugin_type plugin type to validate
|
|
353
353
|
# @return [Boolean]
|
|
354
354
|
def known_type?(plugin_type)
|
|
355
355
|
return true if PLUGIN_TYPES.include?(plugin_type)
|
|
@@ -361,7 +361,7 @@ module Docscribe
|
|
|
361
361
|
# Validate that the class name is a valid Ruby constant name.
|
|
362
362
|
#
|
|
363
363
|
# @private
|
|
364
|
-
# @param [String] class_name class name to validate
|
|
364
|
+
# @param [String?] class_name class name to validate
|
|
365
365
|
# @return [Boolean]
|
|
366
366
|
def valid_name?(class_name)
|
|
367
367
|
return true if valid_constant?(class_name)
|
|
@@ -373,7 +373,7 @@ module Docscribe
|
|
|
373
373
|
# Check whether a string is a valid Ruby constant name.
|
|
374
374
|
#
|
|
375
375
|
# @private
|
|
376
|
-
# @param [String] str
|
|
376
|
+
# @param [String?] str string constant to validate
|
|
377
377
|
# @return [Boolean]
|
|
378
378
|
def valid_constant?(str)
|
|
379
379
|
!!(str =~ /\A[A-Z][A-Za-z0-9]*(?:::[A-Z][A-Za-z0-9]*)*\z/)
|
|
@@ -382,8 +382,8 @@ module Docscribe
|
|
|
382
382
|
# Build the file path for the generated plugin.
|
|
383
383
|
#
|
|
384
384
|
# @private
|
|
385
|
-
# @param [String] class_name CamelCase plugin class name
|
|
386
|
-
# @param [String] output_dir output directory
|
|
385
|
+
# @param [String?] class_name CamelCase plugin class name
|
|
386
|
+
# @param [String?] output_dir output directory
|
|
387
387
|
# @return [String] full file path
|
|
388
388
|
def plugin_path(class_name, output_dir)
|
|
389
389
|
File.join(output_dir || '.', "#{underscore(class_name || '')}.rb")
|
|
@@ -392,7 +392,7 @@ module Docscribe
|
|
|
392
392
|
# Convert CamelCase to snake_case for file naming.
|
|
393
393
|
#
|
|
394
394
|
# @private
|
|
395
|
-
# @param [String] str
|
|
395
|
+
# @param [String] str CamelCase string to convert
|
|
396
396
|
# @return [String]
|
|
397
397
|
def underscore(str)
|
|
398
398
|
str
|
|
@@ -416,9 +416,9 @@ module Docscribe
|
|
|
416
416
|
# Create the output directory and write the plugin file.
|
|
417
417
|
#
|
|
418
418
|
# @private
|
|
419
|
-
# @param [String] output_dir output directory path
|
|
419
|
+
# @param [String?] output_dir output directory path
|
|
420
420
|
# @param [String] path full plugin file path
|
|
421
|
-
# @param [String] content file content to write
|
|
421
|
+
# @param [String?] content file content to write
|
|
422
422
|
# @return [void]
|
|
423
423
|
def write_to_file(output_dir, path, content)
|
|
424
424
|
require 'fileutils'
|
|
@@ -429,7 +429,7 @@ module Docscribe
|
|
|
429
429
|
# Print the creation message and next steps after generating a plugin.
|
|
430
430
|
#
|
|
431
431
|
# @private
|
|
432
|
-
# @param [String] plugin_type 'tag' or 'collector'
|
|
432
|
+
# @param [String?] plugin_type 'tag' or 'collector'
|
|
433
433
|
# @param [String] path file path of the created plugin
|
|
434
434
|
# @return [void]
|
|
435
435
|
def print_created(plugin_type, path)
|
|
@@ -441,8 +441,8 @@ module Docscribe
|
|
|
441
441
|
# Print registration instructions after file creation.
|
|
442
442
|
#
|
|
443
443
|
# @private
|
|
444
|
-
# @param [String] plugin_type
|
|
445
|
-
# @param [String] path
|
|
444
|
+
# @param [String?] plugin_type 'tag' or 'collector'
|
|
445
|
+
# @param [String] path file path
|
|
446
446
|
# @return [String]
|
|
447
447
|
def next_steps(plugin_type, path)
|
|
448
448
|
format(NEXT_STEPS_TEMPLATE,
|
|
@@ -464,8 +464,8 @@ module Docscribe
|
|
|
464
464
|
# Generate an implementation hint string for the given plugin type.
|
|
465
465
|
#
|
|
466
466
|
# @private
|
|
467
|
-
# @param [String] plugin_type 'tag' or 'collector'
|
|
468
|
-
# @return [String] hint text
|
|
467
|
+
# @param [String?] plugin_type 'tag' or 'collector'
|
|
468
|
+
# @return [String, nil] hint text
|
|
469
469
|
def generate_implement_hint(plugin_type)
|
|
470
470
|
case plugin_type
|
|
471
471
|
when 'tag'
|
data/lib/docscribe/cli/init.rb
CHANGED
|
@@ -7,6 +7,14 @@ module Docscribe
|
|
|
7
7
|
module CLI
|
|
8
8
|
# Generate starter Docscribe configuration.
|
|
9
9
|
module Init
|
|
10
|
+
BANNER = <<~TEXT
|
|
11
|
+
Usage: docscribe init [options]
|
|
12
|
+
|
|
13
|
+
Generate a starter docscribe.yml configuration file.
|
|
14
|
+
|
|
15
|
+
Options:
|
|
16
|
+
TEXT
|
|
17
|
+
|
|
10
18
|
class << self
|
|
11
19
|
# Create or print a starter Docscribe configuration file.
|
|
12
20
|
#
|
|
@@ -37,8 +45,8 @@ module Docscribe
|
|
|
37
45
|
# Parse CLI options for `docscribe init`.
|
|
38
46
|
#
|
|
39
47
|
# @private
|
|
40
|
-
# @param [Array<String>] argv
|
|
41
|
-
# @return [Hash] parsed options
|
|
48
|
+
# @param [Array<String>] argv command-line arguments for `docscribe init`
|
|
49
|
+
# @return [Hash<Symbol, Object>] parsed options
|
|
42
50
|
def parse_init_options(argv)
|
|
43
51
|
opts = default_init_options
|
|
44
52
|
build_init_parser(opts).parse!(argv)
|
|
@@ -48,7 +56,7 @@ module Docscribe
|
|
|
48
56
|
# Return the default options hash for the init command.
|
|
49
57
|
#
|
|
50
58
|
# @private
|
|
51
|
-
# @return [Hash]
|
|
59
|
+
# @return [Hash<Symbol, String, Boolean>]
|
|
52
60
|
def default_init_options
|
|
53
61
|
{ config: 'docscribe.yml', force: false, stdout: false, help: false }
|
|
54
62
|
end
|
|
@@ -56,11 +64,11 @@ module Docscribe
|
|
|
56
64
|
# Build and return an OptionParser for the init command.
|
|
57
65
|
#
|
|
58
66
|
# @private
|
|
59
|
-
# @param [Hash] opts options hash that the parser populates
|
|
67
|
+
# @param [Hash<Symbol, Object>] opts options hash that the parser populates
|
|
60
68
|
# @return [OptionParser]
|
|
61
69
|
def build_init_parser(opts)
|
|
62
70
|
OptionParser.new do |o|
|
|
63
|
-
o.banner =
|
|
71
|
+
o.banner = BANNER
|
|
64
72
|
o.on('--config PATH', 'Where to write the config (default: docscribe.yml)') { |v| opts[:config] = v }
|
|
65
73
|
o.on('-f', '--force', 'Overwrite if the file already exists') { opts[:force] = true }
|
|
66
74
|
o.on('--stdout', 'Print config template to STDOUT instead of writing a file') { opts[:stdout] = true }
|
|
@@ -74,7 +82,7 @@ module Docscribe
|
|
|
74
82
|
# Write the config template to a file.
|
|
75
83
|
#
|
|
76
84
|
# @private
|
|
77
|
-
# @param [Hash] opts parsed options
|
|
85
|
+
# @param [Hash<Symbol, Object>] opts parsed options
|
|
78
86
|
# @param [String] yaml config template content
|
|
79
87
|
# @return [Integer] exit code
|
|
80
88
|
def write_init_config(opts, yaml)
|