glib-web 4.39.1 → 4.39.2
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/app/controllers/glib/api_docs_controller.rb +145 -0
- data/app/helpers/glib/json_ui/abstract_builder.rb +16 -0
- data/app/helpers/glib/json_ui/action_builder/dialogs.rb +4 -0
- data/app/helpers/glib/json_ui/list_builders.rb +2 -0
- data/app/helpers/glib/json_ui/view_builder/fields.rb +15 -0
- data/app/helpers/glib/json_ui/view_builder/panels.rb +450 -11
- data/app/helpers/glib/json_ui/view_builder.rb +1 -1
- data/app/views/glib/api_docs/component.json.jbuilder +215 -0
- data/app/views/glib/api_docs/index.json.jbuilder +103 -0
- data/app/views/glib/api_docs/show.json.jbuilder +111 -0
- data/app/views/json_ui/garage/lists/templating.json.jbuilder +68 -44
- data/app/views/json_ui/garage/views/markdowns.json.jbuilder +2 -0
- data/config/routes.rb +4 -0
- data/lib/glib/doc_generator.rb +386 -0
- data/lib/glib/rubocop/cops/test_name_parentheses.rb +33 -0
- data/lib/glib/rubocop.rb +1 -0
- data/lib/tasks/db.rake +1 -1
- data/lib/tasks/docs.rake +59 -0
- metadata +8 -1
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
require 'parser/current'
|
|
2
|
+
require 'yaml'
|
|
3
|
+
require 'fileutils'
|
|
4
|
+
require 'time'
|
|
5
|
+
|
|
6
|
+
module Glib
|
|
7
|
+
class DocGenerator
|
|
8
|
+
def initialize
|
|
9
|
+
@parser = Parser::CurrentRuby
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Generate YAML documentation for a single Ruby file
|
|
13
|
+
def generate_for_file(file_path, output_path)
|
|
14
|
+
unless File.exist?(file_path)
|
|
15
|
+
puts "Warning: File not found: #{file_path}"
|
|
16
|
+
return
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
source = File.read(file_path)
|
|
20
|
+
ast = @parser.parse(source)
|
|
21
|
+
|
|
22
|
+
components = extract_components(ast, source)
|
|
23
|
+
|
|
24
|
+
# Generate YAML
|
|
25
|
+
yaml_data = {
|
|
26
|
+
'meta' => {
|
|
27
|
+
'source_file' => file_path,
|
|
28
|
+
'generated_at' => Time.now.iso8601,
|
|
29
|
+
'generator_version' => '1.0.0'
|
|
30
|
+
},
|
|
31
|
+
'components' => components
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Ensure output directory exists
|
|
35
|
+
FileUtils.mkdir_p(File.dirname(output_path))
|
|
36
|
+
|
|
37
|
+
# Write YAML file
|
|
38
|
+
File.write(output_path, yaml_data.to_yaml)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
# Extract component information from AST
|
|
44
|
+
def extract_components(node, source)
|
|
45
|
+
components = {}
|
|
46
|
+
|
|
47
|
+
traverse_ast(node, source) do |class_node, class_name, parent_class, comment|
|
|
48
|
+
next unless class_node.type == :class
|
|
49
|
+
|
|
50
|
+
# Parse YARD comment
|
|
51
|
+
yard_doc = parse_yard_comment(comment)
|
|
52
|
+
|
|
53
|
+
# Extract properties
|
|
54
|
+
properties = extract_properties(class_node, source)
|
|
55
|
+
|
|
56
|
+
# Build component hash
|
|
57
|
+
component_key = underscore(class_name)
|
|
58
|
+
components[component_key] = {
|
|
59
|
+
'class_name' => class_name,
|
|
60
|
+
'extends' => parent_class,
|
|
61
|
+
'description' => yard_doc[:description],
|
|
62
|
+
'properties' => properties,
|
|
63
|
+
'examples' => yard_doc[:examples],
|
|
64
|
+
'references' => yard_doc[:references],
|
|
65
|
+
'notes' => yard_doc[:notes],
|
|
66
|
+
'deprecated' => yard_doc[:deprecated]
|
|
67
|
+
}.compact
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
components
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Traverse AST and yield class nodes with their comments
|
|
74
|
+
def traverse_ast(node, source, &block)
|
|
75
|
+
return unless node.is_a?(Parser::AST::Node)
|
|
76
|
+
|
|
77
|
+
if node.type == :class
|
|
78
|
+
class_name = extract_class_name(node)
|
|
79
|
+
parent_class = extract_parent_class(node)
|
|
80
|
+
comment = extract_comment(node, source)
|
|
81
|
+
|
|
82
|
+
yield node, class_name, parent_class, comment
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Recursively traverse child nodes
|
|
86
|
+
node.children.each do |child|
|
|
87
|
+
traverse_ast(child, source, &block)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Extract class name from class node
|
|
92
|
+
def extract_class_name(class_node)
|
|
93
|
+
const_node = class_node.children[0]
|
|
94
|
+
if const_node.type == :const
|
|
95
|
+
const_node.children[1].to_s
|
|
96
|
+
else
|
|
97
|
+
'Unknown'
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Extract parent class name
|
|
102
|
+
def extract_parent_class(class_node)
|
|
103
|
+
parent_node = class_node.children[1]
|
|
104
|
+
return nil unless parent_node
|
|
105
|
+
|
|
106
|
+
if parent_node.type == :const
|
|
107
|
+
parent_node.children[1].to_s
|
|
108
|
+
else
|
|
109
|
+
nil
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Extract comment before a node
|
|
114
|
+
def extract_comment(node, source)
|
|
115
|
+
return '' unless node.location
|
|
116
|
+
|
|
117
|
+
# Get all lines before the node
|
|
118
|
+
lines = source.lines
|
|
119
|
+
node_line = node.location.line - 1
|
|
120
|
+
|
|
121
|
+
# Walk backwards to collect comment lines
|
|
122
|
+
comment_lines = []
|
|
123
|
+
(node_line - 1).downto(0) do |i|
|
|
124
|
+
line = lines[i].strip
|
|
125
|
+
break unless line.start_with?('#') || line.empty?
|
|
126
|
+
|
|
127
|
+
if line.start_with?('#')
|
|
128
|
+
# Remove leading # and whitespace
|
|
129
|
+
comment_lines.unshift(line.sub(/^#\s?/, ''))
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
comment_lines.join("\n")
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Parse YARD comment into structured data
|
|
137
|
+
def parse_yard_comment(comment)
|
|
138
|
+
return {} if comment.empty?
|
|
139
|
+
|
|
140
|
+
result = {
|
|
141
|
+
description: '',
|
|
142
|
+
examples: [],
|
|
143
|
+
references: [],
|
|
144
|
+
notes: [],
|
|
145
|
+
deprecated: nil
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
current_section = :description
|
|
149
|
+
current_example = nil
|
|
150
|
+
description_lines = []
|
|
151
|
+
|
|
152
|
+
comment.lines.each do |line|
|
|
153
|
+
line = line.chomp
|
|
154
|
+
|
|
155
|
+
# Check for YARD tags
|
|
156
|
+
if line =~ /^@example\s*(.*)/
|
|
157
|
+
# Save current example if exists
|
|
158
|
+
result[:examples] << current_example if current_example
|
|
159
|
+
|
|
160
|
+
current_example = {
|
|
161
|
+
'label' => $1.strip,
|
|
162
|
+
'code' => ''
|
|
163
|
+
}
|
|
164
|
+
current_section = :example
|
|
165
|
+
elsif line =~ /^@see\s+(.*)/
|
|
166
|
+
reference = $1.strip
|
|
167
|
+
# Parse URL and description
|
|
168
|
+
if reference =~ /^(https?:\/\/\S+)\s+(.*)/
|
|
169
|
+
result[:references] << { 'url' => $1, 'description' => $2 }
|
|
170
|
+
elsif reference =~ /^(https?:\/\/\S+)/
|
|
171
|
+
result[:references] << { 'url' => $1 }
|
|
172
|
+
else
|
|
173
|
+
result[:references] << { 'text' => reference }
|
|
174
|
+
end
|
|
175
|
+
current_section = :description
|
|
176
|
+
elsif line =~ /^@note\s+(.*)/
|
|
177
|
+
result[:notes] << $1.strip
|
|
178
|
+
current_section = :description
|
|
179
|
+
elsif line =~ /^@deprecated\s*(.*)/
|
|
180
|
+
result[:deprecated] = $1.strip
|
|
181
|
+
result[:deprecated] = true if result[:deprecated].empty?
|
|
182
|
+
current_section = :description
|
|
183
|
+
else
|
|
184
|
+
# Regular content
|
|
185
|
+
if current_section == :example && current_example
|
|
186
|
+
# Remove leading spaces from example code (preserve relative indentation)
|
|
187
|
+
current_example['code'] += line + "\n"
|
|
188
|
+
elsif current_section == :description
|
|
189
|
+
description_lines << line unless line.strip.empty? && description_lines.empty?
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Save last example
|
|
195
|
+
result[:examples] << current_example if current_example
|
|
196
|
+
|
|
197
|
+
# Clean up example code (remove extra leading whitespace)
|
|
198
|
+
result[:examples].each do |example|
|
|
199
|
+
example['code'] = unindent(example['code'])
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Join description lines
|
|
203
|
+
result[:description] = description_lines.join("\n").strip
|
|
204
|
+
|
|
205
|
+
# Remove empty arrays/nils
|
|
206
|
+
result.delete(:examples) if result[:examples].empty?
|
|
207
|
+
result.delete(:references) if result[:references].empty?
|
|
208
|
+
result.delete(:notes) if result[:notes].empty?
|
|
209
|
+
result.delete(:deprecated) if result[:deprecated].nil?
|
|
210
|
+
|
|
211
|
+
result
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Extract properties from class body
|
|
215
|
+
def extract_properties(class_node, source)
|
|
216
|
+
properties = {}
|
|
217
|
+
|
|
218
|
+
class_body = class_node.children[2]
|
|
219
|
+
return properties unless class_body
|
|
220
|
+
|
|
221
|
+
traverse_class_body(class_body, source) do |method_name, args, comment|
|
|
222
|
+
# These are the DSL property definition methods
|
|
223
|
+
if [:string, :int, :bool, :float, :action, :views, :array, :hash,
|
|
224
|
+
:icon, :color, :length, :date, :date_time, :text, :any,
|
|
225
|
+
:panels_builder, :menu, :singleton_array].include?(method_name)
|
|
226
|
+
|
|
227
|
+
property_name = args.first
|
|
228
|
+
next unless property_name
|
|
229
|
+
|
|
230
|
+
# Parse property comment
|
|
231
|
+
prop_doc = parse_property_comment(comment)
|
|
232
|
+
|
|
233
|
+
# Extract options if present (for hash, singleton_array, etc.)
|
|
234
|
+
options = extract_property_options(args)
|
|
235
|
+
|
|
236
|
+
properties[property_name] = {
|
|
237
|
+
'type' => method_name.to_s,
|
|
238
|
+
'description' => prop_doc[:description],
|
|
239
|
+
'required' => options[:required] || false,
|
|
240
|
+
'options' => options[:options],
|
|
241
|
+
'examples' => prop_doc[:examples],
|
|
242
|
+
'notes' => prop_doc[:notes],
|
|
243
|
+
'deprecated' => prop_doc[:deprecated]
|
|
244
|
+
}.compact
|
|
245
|
+
|
|
246
|
+
# Remove empty arrays
|
|
247
|
+
properties[property_name].delete('examples') if properties[property_name]['examples']&.empty?
|
|
248
|
+
properties[property_name].delete('notes') if properties[property_name]['notes']&.empty?
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
properties
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Traverse class body to find method calls (property definitions)
|
|
256
|
+
def traverse_class_body(node, source, &block)
|
|
257
|
+
return unless node.is_a?(Parser::AST::Node)
|
|
258
|
+
|
|
259
|
+
if node.type == :send
|
|
260
|
+
receiver = node.children[0]
|
|
261
|
+
method_name = node.children[1]
|
|
262
|
+
args = node.children[2..-1].map { |arg| extract_symbol_or_string(arg) }
|
|
263
|
+
comment = extract_comment(node, source)
|
|
264
|
+
|
|
265
|
+
# Only process calls without a receiver (DSL methods)
|
|
266
|
+
yield method_name, args, comment if receiver.nil?
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
node.children.each do |child|
|
|
270
|
+
traverse_class_body(child, source, &block)
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Extract symbol or string value from AST node
|
|
275
|
+
def extract_symbol_or_string(node)
|
|
276
|
+
return nil unless node.is_a?(Parser::AST::Node)
|
|
277
|
+
|
|
278
|
+
case node.type
|
|
279
|
+
when :sym
|
|
280
|
+
node.children[0].to_s
|
|
281
|
+
when :str
|
|
282
|
+
node.children[0]
|
|
283
|
+
when :hash
|
|
284
|
+
extract_hash(node)
|
|
285
|
+
else
|
|
286
|
+
nil
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
# Extract hash from AST node
|
|
291
|
+
def extract_hash(node)
|
|
292
|
+
return nil unless node.type == :hash
|
|
293
|
+
|
|
294
|
+
result = {}
|
|
295
|
+
node.children.each do |pair|
|
|
296
|
+
next unless pair.type == :pair
|
|
297
|
+
key = extract_symbol_or_string(pair.children[0])
|
|
298
|
+
value = extract_symbol_or_string(pair.children[1]) || extract_array(pair.children[1])
|
|
299
|
+
result[key] = value if key
|
|
300
|
+
end
|
|
301
|
+
result
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# Extract array from AST node
|
|
305
|
+
def extract_array(node)
|
|
306
|
+
return nil unless node.is_a?(Parser::AST::Node) && node.type == :array
|
|
307
|
+
|
|
308
|
+
node.children.map { |child| extract_symbol_or_string(child) }.compact
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
# Extract property options from arguments
|
|
312
|
+
def extract_property_options(args)
|
|
313
|
+
options = { required: false }
|
|
314
|
+
|
|
315
|
+
args.each do |arg|
|
|
316
|
+
if arg.is_a?(Hash)
|
|
317
|
+
if arg['required']
|
|
318
|
+
options[:required] = true
|
|
319
|
+
end
|
|
320
|
+
if arg['optional']
|
|
321
|
+
options[:options] = { 'optional' => arg['optional'] }
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
options
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
# Parse property comment
|
|
330
|
+
def parse_property_comment(comment)
|
|
331
|
+
return {} if comment.empty?
|
|
332
|
+
|
|
333
|
+
result = {
|
|
334
|
+
description: '',
|
|
335
|
+
examples: [],
|
|
336
|
+
notes: [],
|
|
337
|
+
deprecated: nil
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
description_lines = []
|
|
341
|
+
|
|
342
|
+
comment.lines.each do |line|
|
|
343
|
+
line = line.chomp
|
|
344
|
+
|
|
345
|
+
if line =~ /^@example\s+(.*)/
|
|
346
|
+
result[:examples] << $1.strip
|
|
347
|
+
elsif line =~ /^@note\s+(.*)/
|
|
348
|
+
result[:notes] << $1.strip
|
|
349
|
+
elsif line =~ /^@deprecated\s*(.*)/
|
|
350
|
+
result[:deprecated] = $1.strip
|
|
351
|
+
result[:deprecated] = true if result[:deprecated].empty?
|
|
352
|
+
else
|
|
353
|
+
description_lines << line unless line.strip.empty? && description_lines.empty?
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
result[:description] = description_lines.join("\n").strip
|
|
358
|
+
|
|
359
|
+
result
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
# Convert CamelCase to snake_case
|
|
363
|
+
def underscore(string)
|
|
364
|
+
string.gsub(/::/, '_')
|
|
365
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
|
366
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
|
367
|
+
.tr('-', '_')
|
|
368
|
+
.downcase
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
# Remove common leading whitespace from multi-line strings
|
|
372
|
+
def unindent(text)
|
|
373
|
+
return text if text.empty?
|
|
374
|
+
|
|
375
|
+
lines = text.lines
|
|
376
|
+
# Find minimum indentation (ignoring empty lines)
|
|
377
|
+
min_indent = lines
|
|
378
|
+
.reject { |line| line.strip.empty? }
|
|
379
|
+
.map { |line| line.match(/^(\s*)/)[1].length }
|
|
380
|
+
.min || 0
|
|
381
|
+
|
|
382
|
+
# Remove that amount of indentation from each line
|
|
383
|
+
lines.map { |line| line.strip.empty? ? line : line[min_indent..-1] }.join
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RuboCop
|
|
4
|
+
module Cop
|
|
5
|
+
module Glib
|
|
6
|
+
# Prevents test method names from containing parentheses which can cause issues with test runners
|
|
7
|
+
#
|
|
8
|
+
# @example
|
|
9
|
+
# # bad
|
|
10
|
+
# test 'user creation (with email)' do
|
|
11
|
+
# end
|
|
12
|
+
#
|
|
13
|
+
# # good
|
|
14
|
+
# test 'user creation with email' do
|
|
15
|
+
# end
|
|
16
|
+
class TestNameParentheses < Base
|
|
17
|
+
MSG = "Test name should not contain parentheses because for some reason, this will produce: 'Syntax error: \"(\" unexpected'."
|
|
18
|
+
|
|
19
|
+
def_node_matcher :test_method?, <<~PATTERN
|
|
20
|
+
(send nil? :test (str $_) ...)
|
|
21
|
+
PATTERN
|
|
22
|
+
|
|
23
|
+
def on_send(node)
|
|
24
|
+
test_method?(node) do |test_name|
|
|
25
|
+
if test_name.include?('(') || test_name.include?(')')
|
|
26
|
+
add_offense(node)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
data/lib/glib/rubocop.rb
CHANGED
|
@@ -3,3 +3,4 @@ require_relative 'rubocop/cops/multiline_method_call_style'
|
|
|
3
3
|
require_relative 'rubocop/cops/json_ui/base_nested_parameter'
|
|
4
4
|
require_relative 'rubocop/cops/json_ui/nested_block_parameter'
|
|
5
5
|
require_relative 'rubocop/cops/json_ui/nested_action_parameter'
|
|
6
|
+
require_relative 'rubocop/cops/test_name_parentheses'
|
data/lib/tasks/db.rake
CHANGED
data/lib/tasks/docs.rake
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
namespace :glib do
|
|
2
|
+
namespace :docs do
|
|
3
|
+
desc 'Generate component documentation in YAML format'
|
|
4
|
+
task :generate do
|
|
5
|
+
require_relative '../glib/doc_generator'
|
|
6
|
+
|
|
7
|
+
generator = Glib::DocGenerator.new
|
|
8
|
+
|
|
9
|
+
# Generate documentation for different component categories
|
|
10
|
+
categories = [
|
|
11
|
+
{
|
|
12
|
+
name: 'panels',
|
|
13
|
+
file: 'app/helpers/glib/json_ui/view_builder/panels.rb',
|
|
14
|
+
output: 'doc/components/panels.yml'
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'fields',
|
|
18
|
+
file: 'app/helpers/glib/json_ui/view_builder/fields.rb',
|
|
19
|
+
output: 'doc/components/fields.yml'
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'views',
|
|
23
|
+
file: 'app/helpers/glib/json_ui/view_builder.rb',
|
|
24
|
+
output: 'doc/components/views.yml'
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: 'actions',
|
|
28
|
+
file: 'app/helpers/glib/json_ui/action_builder.rb',
|
|
29
|
+
output: 'doc/components/actions.yml'
|
|
30
|
+
}
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
categories.each do |category|
|
|
34
|
+
puts "Generating documentation for #{category[:name]}..."
|
|
35
|
+
generator.generate_for_file(category[:file], category[:output])
|
|
36
|
+
puts " -> #{category[:output]}"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Also scan action subdirectories
|
|
40
|
+
Dir.glob('app/helpers/glib/json_ui/action_builder/*.rb').each do |file|
|
|
41
|
+
basename = File.basename(file, '.rb')
|
|
42
|
+
output = "doc/components/actions_#{basename}.yml"
|
|
43
|
+
puts "Generating documentation for actions/#{basename}..."
|
|
44
|
+
generator.generate_for_file(file, output)
|
|
45
|
+
puts " -> #{output}"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
puts "\nDocumentation generation complete!"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
desc 'Validate YARD documentation'
|
|
52
|
+
task :validate do
|
|
53
|
+
puts "Validating YARD documentation..."
|
|
54
|
+
system('yard stats --list-undoc')
|
|
55
|
+
system('yard doc --fail-on-warning --no-output')
|
|
56
|
+
puts "\nValidation complete!"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: glib-web
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.39.
|
|
4
|
+
version: 4.39.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ''
|
|
@@ -156,6 +156,7 @@ files:
|
|
|
156
156
|
- app/controllers/concerns/glib/json/traversal.rb
|
|
157
157
|
- app/controllers/concerns/glib/json/ui.rb
|
|
158
158
|
- app/controllers/concerns/glib/json/validation.rb
|
|
159
|
+
- app/controllers/glib/api_docs_controller.rb
|
|
159
160
|
- app/controllers/glib/blob_url_generators_controller.rb
|
|
160
161
|
- app/controllers/glib/errors_controller.rb
|
|
161
162
|
- app/controllers/glib/glib_direct_uploads_controller.rb
|
|
@@ -220,6 +221,9 @@ files:
|
|
|
220
221
|
- app/validators/mutually_exclusive_with_validator.rb
|
|
221
222
|
- app/validators/presence_only_if_validator.rb
|
|
222
223
|
- app/validators/url_validator.rb
|
|
224
|
+
- app/views/glib/api_docs/component.json.jbuilder
|
|
225
|
+
- app/views/glib/api_docs/index.json.jbuilder
|
|
226
|
+
- app/views/glib/api_docs/show.json.jbuilder
|
|
223
227
|
- app/views/json_ui/garage/_nav_menu.json.jbuilder
|
|
224
228
|
- app/views/json_ui/garage/actions/_commands.json.jbuilder
|
|
225
229
|
- app/views/json_ui/garage/actions/_components.json.jbuilder
|
|
@@ -423,6 +427,7 @@ files:
|
|
|
423
427
|
- lib/glib-web.rb
|
|
424
428
|
- lib/glib/all_helpers.rb
|
|
425
429
|
- lib/glib/crypt/utils.rb
|
|
430
|
+
- lib/glib/doc_generator.rb
|
|
426
431
|
- lib/glib/dynamic_text.rb
|
|
427
432
|
- lib/glib/dynamic_text/config.rb
|
|
428
433
|
- lib/glib/engine.rb
|
|
@@ -448,6 +453,7 @@ files:
|
|
|
448
453
|
- lib/glib/rubocop/cops/json_ui/nested_block_parameter.rb
|
|
449
454
|
- lib/glib/rubocop/cops/localize.rb
|
|
450
455
|
- lib/glib/rubocop/cops/multiline_method_call_style.rb
|
|
456
|
+
- lib/glib/rubocop/cops/test_name_parentheses.rb
|
|
451
457
|
- lib/glib/snapshot.rb
|
|
452
458
|
- lib/glib/test/parallel_coverage.rb
|
|
453
459
|
- lib/glib/test_helpers.rb
|
|
@@ -456,6 +462,7 @@ files:
|
|
|
456
462
|
- lib/glib/value.rb
|
|
457
463
|
- lib/glib/version.rb
|
|
458
464
|
- lib/tasks/db.rake
|
|
465
|
+
- lib/tasks/docs.rake
|
|
459
466
|
homepage:
|
|
460
467
|
licenses: []
|
|
461
468
|
metadata: {}
|