ariadne_view_components 0.0.45-arm64-darwin → 0.0.46-arm64-darwin
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/CHANGELOG.md +4 -0
- data/lib/ariadne/view_components/version.rb +1 -1
- metadata +1 -12
- data/lib/tasks/ariadne_view_components.rake +0 -48
- data/lib/tasks/build.rake +0 -30
- data/lib/tasks/coverage.rake +0 -20
- data/lib/tasks/docs.rake +0 -466
- data/lib/tasks/helpers/ast_processor.rb +0 -44
- data/lib/tasks/helpers/ast_traverser.rb +0 -77
- data/lib/tasks/static.rake +0 -15
- data/lib/tasks/test.rake +0 -19
- data/lib/yard/docs_helper.rb +0 -90
- data/lib/yard/renders_many_handler.rb +0 -19
- data/lib/yard/renders_one_handler.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b93c6655d9e580374c658a8886eb2c46396295fbc46c4c06167135803df1a098
|
4
|
+
data.tar.gz: 9f2a463ae9d84e5e9264c5d66f39a41c00a49c383da58df6a8c30161e0e383b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81495b17e7196ac81679f7dbbe207900fd60a576fc4a6e47b9873db11eee1a6e92abf1f338f503292743580cabae470a17bd754871c3ace85d04961a7d939b0b
|
7
|
+
data.tar.gz: '028cebabb299445af1725a47de65167c916052736d20ee54458d8907174db7760e96d786620e06372d0f45f103f3f90e30bdf3c0bdf730b6459d80449c4ad0a3'
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v0.0.45](https://github.com/yettoapp/ariadne/tree/v0.0.45) (2023-05-04)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/yettoapp/ariadne/compare/v0.0.44...v0.0.45)
|
6
|
+
|
3
7
|
## [v0.0.44](https://github.com/yettoapp/ariadne/tree/v0.0.44) (2023-05-04)
|
4
8
|
|
5
9
|
[Full Changelog](https://github.com/yettoapp/ariadne/compare/v0.0.43...v0.0.44)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ariadne_view_components
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.46
|
5
5
|
platform: arm64-darwin
|
6
6
|
authors:
|
7
7
|
- Garen J. Torikian
|
@@ -250,17 +250,6 @@ files:
|
|
250
250
|
- lib/rubocop/cop/ariadne.rb
|
251
251
|
- lib/rubocop/cop/ariadne/base_cop.rb
|
252
252
|
- lib/rubocop/cop/ariadne/no_tag_memoize.rb
|
253
|
-
- lib/tasks/ariadne_view_components.rake
|
254
|
-
- lib/tasks/build.rake
|
255
|
-
- lib/tasks/coverage.rake
|
256
|
-
- lib/tasks/docs.rake
|
257
|
-
- lib/tasks/helpers/ast_processor.rb
|
258
|
-
- lib/tasks/helpers/ast_traverser.rb
|
259
|
-
- lib/tasks/static.rake
|
260
|
-
- lib/tasks/test.rake
|
261
|
-
- lib/yard/docs_helper.rb
|
262
|
-
- lib/yard/renders_many_handler.rb
|
263
|
-
- lib/yard/renders_one_handler.rb
|
264
253
|
- static/arguments.yml
|
265
254
|
- static/assets/view-components.svg
|
266
255
|
- static/audited_at.json
|
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
ERB_GLOB = "**/*.html{+*,}.erb"
|
4
|
-
RB_GLOB = "**/*.rb"
|
5
|
-
# copied from Rails: action_view/template/handlers/erb/erubi.rb
|
6
|
-
BLOCK_EXPR = /\s*((\s+|\))do|\{)(\s*\|[^|]*\|)?\s*\Z/
|
7
|
-
|
8
|
-
namespace :ariadne_view_components do
|
9
|
-
desc "Report arguments used in each component"
|
10
|
-
task :report, [:paths] do |_, args|
|
11
|
-
require "rubocop"
|
12
|
-
require "better_html"
|
13
|
-
require "better_html/parser"
|
14
|
-
require "erb_lint/processed_source"
|
15
|
-
require_relative "helpers/ast_processor"
|
16
|
-
|
17
|
-
paths = args[:paths].split
|
18
|
-
stats = {}
|
19
|
-
|
20
|
-
rb_files = paths.reduce([]) { |mem, path| mem + Dir[File.join(path, RB_GLOB)] }
|
21
|
-
|
22
|
-
rb_files.each do |f|
|
23
|
-
ast = RuboCop::AST::ProcessedSource.from_file(f, RUBY_VERSION.to_f).ast
|
24
|
-
AstProcessor.process_ast(ast, stats)
|
25
|
-
end
|
26
|
-
|
27
|
-
erb_files = paths.reduce([]) { |mem, path| mem + Dir[File.join(path, ERB_GLOB)] }
|
28
|
-
|
29
|
-
erb_files.each do |f|
|
30
|
-
erb_ast = ERBLint::ProcessedSource.new(f, File.read(f)).ast
|
31
|
-
|
32
|
-
erb_ast.descendants(:erb).each do |erb_node|
|
33
|
-
indicator, _, code_node, = *erb_node
|
34
|
-
|
35
|
-
next if indicator&.children&.first == "#" # don't analyze comments
|
36
|
-
|
37
|
-
trimmed_source = code_node.loc.source.sub(BLOCK_EXPR, "").strip
|
38
|
-
ast = RuboCop::AST::ProcessedSource.new(trimmed_source, RUBY_VERSION.to_f).ast
|
39
|
-
AstProcessor.process_ast(ast, stats)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
File.open(".ariadne-view-components-report.json", "w") do |f|
|
44
|
-
f.write(JSON.pretty_generate(stats))
|
45
|
-
f.write($INPUT_RECORD_SEPARATOR)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
data/lib/tasks/build.rake
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "ariadne/view_components/commands"
|
4
|
-
|
5
|
-
namespace :ariadne_view_components do
|
6
|
-
desc "Build Ariadne View Components CSS"
|
7
|
-
task :build do |_, args|
|
8
|
-
debug = args.extras.include?("debug")
|
9
|
-
command = Ariadne::ViewComponents::Commands.compile_command(debug: debug)
|
10
|
-
puts command.inspect
|
11
|
-
system(*command, exception: true)
|
12
|
-
end
|
13
|
-
|
14
|
-
desc "Watch and build Ariadne View Components CSS on file changes"
|
15
|
-
task :watch do |_, args|
|
16
|
-
debug = args.extras.include?("debug")
|
17
|
-
poll = args.extras.include?("poll")
|
18
|
-
command = Ariadne::ViewComponents::Commands.watch_command(debug: debug, poll: poll)
|
19
|
-
puts command.inspect
|
20
|
-
system(*command)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
Rake::Task["assets:precompile"].enhance(["ariadne_view_components:build"]) if Rake::Task.task_defined?("assets:precompile")
|
25
|
-
|
26
|
-
if Rake::Task.task_defined?("test:prepare")
|
27
|
-
Rake::Task["test:prepare"].enhance(["ariadne_view_components:build"])
|
28
|
-
elsif Rake::Task.task_defined?("db:test:prepare")
|
29
|
-
Rake::Task["db:test:prepare"].enhance(["ariadne_view_components:build"])
|
30
|
-
end
|
data/lib/tasks/coverage.rake
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
namespace :coverage do
|
4
|
-
desc "Run coverage report. This should ideally be done only on CI."
|
5
|
-
task :report do
|
6
|
-
require "simplecov"
|
7
|
-
require "simplecov-console"
|
8
|
-
|
9
|
-
SimpleCov.collate(Dir["coverage/.resultset.json"], "rails") do
|
10
|
-
formatter SimpleCov::Formatter::Console
|
11
|
-
|
12
|
-
minimum_coverage 100
|
13
|
-
maximum_coverage_drop 2
|
14
|
-
|
15
|
-
add_group "Ignored Code" do |src_file|
|
16
|
-
File.readlines(src_file.filename).grep(/:nocov:/).any?
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
data/lib/tasks/docs.rake
DELETED
@@ -1,466 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "yard"
|
4
|
-
require "yard/renders_one_handler"
|
5
|
-
require "yard/renders_many_handler"
|
6
|
-
|
7
|
-
require "active_support/inflector"
|
8
|
-
require "fileutils"
|
9
|
-
|
10
|
-
namespace :docs do
|
11
|
-
desc "Rebuilds docs on change; run via the Procfile"
|
12
|
-
task :watch do
|
13
|
-
require "listen"
|
14
|
-
|
15
|
-
Rake::Task["docs:build"].execute
|
16
|
-
|
17
|
-
puts "Listening for changes to documentation..."
|
18
|
-
|
19
|
-
listener = Listen.to("app") do |modified, added, removed|
|
20
|
-
puts "modified absolute path: #{modified}"
|
21
|
-
puts "added absolute path: #{added}"
|
22
|
-
puts "removed absolute path: #{removed}"
|
23
|
-
|
24
|
-
if modified.length.nonzero?
|
25
|
-
changed = modified.dup.uniq
|
26
|
-
while (path = changed.shift)
|
27
|
-
puts "Reloading #{path}"
|
28
|
-
# reload constants (in case they changed)
|
29
|
-
load(path)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
Rake::Task["docs:build"].execute
|
34
|
-
end
|
35
|
-
listener.start # not blocking
|
36
|
-
sleep
|
37
|
-
end
|
38
|
-
|
39
|
-
# for classes in hashes
|
40
|
-
CLASS_MAPPINGS = '(?:\\S+|:\\"[\\S-]+\\"): \\"([\\S -]+)\\"'
|
41
|
-
# for classes in constants
|
42
|
-
CLASS_CONSTANT = '[A-Z_]+ = \\"([\\S -]+)\\"'
|
43
|
-
CLASS_REGEX = Regexp.new("(?:#{CLASS_MAPPINGS}|#{CLASS_CONSTANT})")
|
44
|
-
|
45
|
-
desc "Generate the documentation."
|
46
|
-
task :build do
|
47
|
-
registry = generate_yard_registry
|
48
|
-
|
49
|
-
puts "Converting YARD documentation to Markdown files."
|
50
|
-
|
51
|
-
# Rails controller for rendering arbitrary ERB
|
52
|
-
view_context = ApplicationController.new.tap { |c| c.request = ActionDispatch::TestRequest.create }.view_context
|
53
|
-
components = [
|
54
|
-
Ariadne::AvatarComponent,
|
55
|
-
Ariadne::AvatarStackComponent,
|
56
|
-
Ariadne::CommentComponent,
|
57
|
-
Ariadne::BodyComponent,
|
58
|
-
Ariadne::BlankslateComponent,
|
59
|
-
Ariadne::BaseButton,
|
60
|
-
Ariadne::ButtonComponent,
|
61
|
-
Ariadne::ContainerComponent,
|
62
|
-
Ariadne::ClipboardCopyComponent,
|
63
|
-
Ariadne::CounterComponent,
|
64
|
-
Ariadne::DetailsComponent,
|
65
|
-
Ariadne::DropdownComponent,
|
66
|
-
Ariadne::GridComponent,
|
67
|
-
Ariadne::FlashComponent,
|
68
|
-
Ariadne::FlexComponent,
|
69
|
-
Ariadne::FooterComponent,
|
70
|
-
Ariadne::HeaderComponent,
|
71
|
-
Ariadne::HeadingComponent,
|
72
|
-
Ariadne::HeroiconComponent,
|
73
|
-
Ariadne::ImageComponent,
|
74
|
-
Ariadne::InlineFlexComponent,
|
75
|
-
Ariadne::LinkComponent,
|
76
|
-
Ariadne::ListComponent,
|
77
|
-
Ariadne::NarrowContainerComponent,
|
78
|
-
Ariadne::PanelBarComponent,
|
79
|
-
Ariadne::PillComponent,
|
80
|
-
Ariadne::RichTextAreaComponent,
|
81
|
-
Ariadne::SlideoverComponent,
|
82
|
-
Ariadne::TabComponent,
|
83
|
-
Ariadne::TabContainerComponent,
|
84
|
-
Ariadne::TableNavComponent,
|
85
|
-
Ariadne::TabNavComponent,
|
86
|
-
Ariadne::Text,
|
87
|
-
Ariadne::TimeAgoComponent,
|
88
|
-
Ariadne::TimelineComponent,
|
89
|
-
Ariadne::TooltipComponent,
|
90
|
-
]
|
91
|
-
|
92
|
-
# TODO: Form is not in documentation
|
93
|
-
js_components = [
|
94
|
-
Ariadne::ClipboardCopyComponent,
|
95
|
-
Ariadne::RichTextAreaComponent,
|
96
|
-
Ariadne::SlideoverComponent,
|
97
|
-
Ariadne::TabContainerComponent,
|
98
|
-
Ariadne::TabNavComponent,
|
99
|
-
Ariadne::TimeAgoComponent,
|
100
|
-
Ariadne::TooltipComponent,
|
101
|
-
]
|
102
|
-
|
103
|
-
all_components = Ariadne::Component.descendants - [Ariadne::BaseComponent, Ariadne::Content] # TODO: why is `Ariadne::Content` not picked up?
|
104
|
-
components_needing_docs = all_components - components
|
105
|
-
|
106
|
-
args_for_components = []
|
107
|
-
classes_found_in_examples = []
|
108
|
-
|
109
|
-
errors = []
|
110
|
-
|
111
|
-
# Deletes docs before regenerating them, guaranteeing that we don't keep stale docs.
|
112
|
-
components_content_glob = File.join("docs", "content", "components", "**", "*.md")
|
113
|
-
FileUtils.rm_rf(components_content_glob)
|
114
|
-
|
115
|
-
components.sort_by(&:name).each do |component|
|
116
|
-
documentation = registry.get(component.name)
|
117
|
-
|
118
|
-
data = docs_metadata(component)
|
119
|
-
|
120
|
-
path = Pathname.new(data[:path])
|
121
|
-
path.dirname.mkpath unless path.dirname.exist?
|
122
|
-
File.open(path, "w") do |f|
|
123
|
-
f.puts("---")
|
124
|
-
f.puts("title: #{data[:title]}")
|
125
|
-
f.puts("componentId: #{data[:component_id]}")
|
126
|
-
f.puts("status: #{data[:status]}")
|
127
|
-
f.puts("source: #{data[:source]}")
|
128
|
-
f.puts("lookbook: #{data[:lookbook]}")
|
129
|
-
f.puts("---")
|
130
|
-
f.puts
|
131
|
-
f.puts("import Example from '#{data[:example_path]}'")
|
132
|
-
|
133
|
-
initialize_method = documentation.meths.find(&:constructor?)
|
134
|
-
|
135
|
-
if js_components.include?(component)
|
136
|
-
f.puts("import RequiresJSFlash from '#{data[:require_js_path]}'")
|
137
|
-
f.puts
|
138
|
-
f.puts("<RequiresJSFlash />")
|
139
|
-
end
|
140
|
-
|
141
|
-
f.puts
|
142
|
-
f.puts("<!-- Warning: AUTO-GENERATED file, do not edit. Add code comments to your Ruby instead <3 -->")
|
143
|
-
f.puts
|
144
|
-
f.puts(view_context.render(inline: documentation.base_docstring))
|
145
|
-
|
146
|
-
if documentation.tags(:deprecated).any?
|
147
|
-
f.puts
|
148
|
-
f.puts("## Deprecation")
|
149
|
-
documentation.tags(:deprecated).each do |tag|
|
150
|
-
f.puts
|
151
|
-
f.puts view_context.render(inline: tag.text)
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
if documentation.tags(:accessibility).any?
|
156
|
-
f.puts
|
157
|
-
f.puts("## Accessibility")
|
158
|
-
documentation.tags(:accessibility).each do |tag|
|
159
|
-
f.puts
|
160
|
-
f.puts view_context.render(inline: tag.text)
|
161
|
-
end
|
162
|
-
end
|
163
|
-
|
164
|
-
params = initialize_method.tags(:param)
|
165
|
-
|
166
|
-
errors << { component.name => { arguments: "No argument documentation found" } } if params.none?
|
167
|
-
|
168
|
-
f.puts
|
169
|
-
f.puts("## Arguments")
|
170
|
-
f.puts
|
171
|
-
f.puts("| Name | Type | Default | Description |")
|
172
|
-
f.puts("| :- | :- | :- | :- |")
|
173
|
-
|
174
|
-
documented_params = params.map(&:name)
|
175
|
-
component_params = component.instance_method(:initialize).parameters.map { |p| p.last.to_s }
|
176
|
-
|
177
|
-
if (documented_params & component_params).size != component_params.size
|
178
|
-
err = { arguments: {} }
|
179
|
-
(component_params - documented_params).each do |arg|
|
180
|
-
err[:arguments][arg] = "Not documented"
|
181
|
-
end
|
182
|
-
|
183
|
-
errors << { component.name => err }
|
184
|
-
end
|
185
|
-
|
186
|
-
args = []
|
187
|
-
params.each do |tag|
|
188
|
-
default_value = pretty_default_value(tag, component)
|
189
|
-
|
190
|
-
args << {
|
191
|
-
"name" => tag.name,
|
192
|
-
"type" => tag.types.join(", "),
|
193
|
-
"default" => default_value,
|
194
|
-
"description" => view_context.render(inline: tag.text.squish),
|
195
|
-
}
|
196
|
-
|
197
|
-
f.puts("| `#{tag.name}` | `#{tag.types.join(", ")}` | #{default_value} | #{view_context.render(inline: tag.text.squish)} |")
|
198
|
-
end
|
199
|
-
|
200
|
-
component_args = {
|
201
|
-
"component" => data[:title],
|
202
|
-
"source" => data[:source],
|
203
|
-
"parameters" => args,
|
204
|
-
}
|
205
|
-
|
206
|
-
args_for_components << component_args
|
207
|
-
|
208
|
-
# Slots V2 docs
|
209
|
-
slot_v2_methods = documentation.meths.select { |x| x[:renders_one] || x[:renders_many] }
|
210
|
-
|
211
|
-
if slot_v2_methods.any?
|
212
|
-
f.puts
|
213
|
-
f.puts("## Slots")
|
214
|
-
|
215
|
-
slot_v2_methods.each do |slot_documentation|
|
216
|
-
f.puts
|
217
|
-
f.puts("### `#{slot_documentation.name.to_s.capitalize}`")
|
218
|
-
|
219
|
-
if slot_documentation.base_docstring.to_s.present?
|
220
|
-
f.puts
|
221
|
-
f.puts(view_context.render(inline: slot_documentation.base_docstring))
|
222
|
-
end
|
223
|
-
|
224
|
-
param_tags = slot_documentation.tags(:param)
|
225
|
-
if param_tags.any?
|
226
|
-
f.puts
|
227
|
-
f.puts("| Name | Type | Default | Description |")
|
228
|
-
f.puts("| :- | :- | :- | :- |")
|
229
|
-
end
|
230
|
-
|
231
|
-
param_tags.each do |tag|
|
232
|
-
f.puts("| `#{tag.name}` | `#{tag.types.join(", ")}` | #{pretty_default_value(tag, component)} | #{view_context.render(inline: tag.text)} |")
|
233
|
-
end
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
|
-
example_tags = initialize_method.tags(:example)
|
238
|
-
|
239
|
-
if example_tags.any?
|
240
|
-
f.puts
|
241
|
-
f.puts("## Examples")
|
242
|
-
|
243
|
-
example_tags.each do |tag|
|
244
|
-
name, description, code = parse_example_tag(tag)
|
245
|
-
f.puts
|
246
|
-
f.puts("### #{name}")
|
247
|
-
if description
|
248
|
-
f.puts
|
249
|
-
f.puts(view_context.render(inline: description.squish))
|
250
|
-
end
|
251
|
-
f.puts
|
252
|
-
html = begin
|
253
|
-
view_context.render(inline: code)
|
254
|
-
rescue StandardError => e
|
255
|
-
raise StandardError, "Unexpected error with #{data[:title]}: #{e.message}"
|
256
|
-
end
|
257
|
-
html.scan(/class="([^"]*)"/) do |classnames|
|
258
|
-
classes_found_in_examples.concat(classnames[0].split.reject { |c| c.starts_with?("heroicon", "js") }.map { ".#{_1}" })
|
259
|
-
end
|
260
|
-
f.puts("<Example src=\"#{html.tr('"', "'").delete("\n")}\" />")
|
261
|
-
f.puts
|
262
|
-
f.puts("```erb")
|
263
|
-
f.puts(code.to_s)
|
264
|
-
f.puts("```")
|
265
|
-
end
|
266
|
-
else
|
267
|
-
errors << { component.name => { example: "No examples found" } } unless components_without_examples.include?(component)
|
268
|
-
end
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
|
-
unless errors.empty?
|
273
|
-
puts "==============================================="
|
274
|
-
puts "===================== ERRORS =================="
|
275
|
-
puts "===============================================\n\n"
|
276
|
-
puts JSON.pretty_generate(errors)
|
277
|
-
puts "\n\n==============================================="
|
278
|
-
puts "==============================================="
|
279
|
-
puts "==============================================="
|
280
|
-
|
281
|
-
raise
|
282
|
-
end
|
283
|
-
|
284
|
-
File.open("static/classes.yml", "w") do |f|
|
285
|
-
non_ariadne_classes = classes_found_in_examples.reject { |c| c =~ /(?:ariadne|tiptap)/ }.uniq
|
286
|
-
if non_ariadne_classes.length.nonzero?
|
287
|
-
puts "==============================================="
|
288
|
-
puts "===================== ERRORS =================="
|
289
|
-
puts "===============================================\n\n"
|
290
|
-
puts "The following non-Ariadne classes were found: #{non_ariadne_classes.join(", ")}"
|
291
|
-
puts "\n\n==============================================="
|
292
|
-
puts "==============================================="
|
293
|
-
puts "==============================================="
|
294
|
-
|
295
|
-
raise
|
296
|
-
end
|
297
|
-
|
298
|
-
f.puts YAML.dump(classes_found_in_examples.uniq)
|
299
|
-
end
|
300
|
-
|
301
|
-
File.open("static/arguments.yml", "w") do |f|
|
302
|
-
f.puts YAML.dump(args_for_components)
|
303
|
-
end
|
304
|
-
|
305
|
-
puts "Markdown compiled."
|
306
|
-
|
307
|
-
if components_needing_docs.any?
|
308
|
-
puts "\nThe following components need documentation. Could you add it to them? \n* #{components_needing_docs.map(&:name).join("\n* ")}"
|
309
|
-
end
|
310
|
-
end
|
311
|
-
|
312
|
-
desc "Generate previews from documentation examples"
|
313
|
-
task :preview do
|
314
|
-
registry = generate_yard_registry
|
315
|
-
|
316
|
-
FileUtils.rm_rf("lookbook/test/components/previews/ariadne/docs/")
|
317
|
-
|
318
|
-
components = Ariadne::Component.descendants
|
319
|
-
|
320
|
-
components.each do |component|
|
321
|
-
documentation = registry.get(component.name)
|
322
|
-
short_name = component.name.gsub(/Ariadne|::/, "")
|
323
|
-
initialize_method = documentation.meths.find(&:constructor?)
|
324
|
-
|
325
|
-
next unless initialize_method&.tags(:example)&.any?
|
326
|
-
|
327
|
-
yard_example_tags = initialize_method.tags(:example)
|
328
|
-
|
329
|
-
path = Pathname.new("lookbook/test/components/previews/ariadne/docs/#{short_name.underscore}_preview.rb")
|
330
|
-
FileUtils.mkdir_p("lookbook/test/components/previews/ariadne/docs") unless path.dirname.exist?
|
331
|
-
|
332
|
-
File.open(path, "w") do |f|
|
333
|
-
f.puts("module Ariadne")
|
334
|
-
f.puts(" module Docs")
|
335
|
-
f.puts(" class #{short_name}Preview < ViewComponent::Preview")
|
336
|
-
|
337
|
-
yard_example_tags.each_with_index do |tag, index|
|
338
|
-
name, _, code = parse_example_tag(tag)
|
339
|
-
method_name = name.split("|").first.downcase.parameterize.underscore
|
340
|
-
f.puts(" def #{method_name}; end")
|
341
|
-
f.puts unless index == yard_example_tags.size - 1
|
342
|
-
path = Pathname.new("lookbook/test/components/previews/ariadne/docs/#{short_name.underscore}_preview/#{method_name}.html.erb")
|
343
|
-
FileUtils.mkdir_p("lookbook/test/components/previews/ariadne/docs/#{short_name.underscore}_preview") unless path.dirname.exist?
|
344
|
-
File.open(path, "w") do |view_file|
|
345
|
-
view_file.puts(code.to_s)
|
346
|
-
end
|
347
|
-
end
|
348
|
-
|
349
|
-
f.puts(" end")
|
350
|
-
f.puts(" end")
|
351
|
-
f.puts("end")
|
352
|
-
end
|
353
|
-
end
|
354
|
-
end
|
355
|
-
end
|
356
|
-
|
357
|
-
def generate_yard_registry
|
358
|
-
require "action_dispatch"
|
359
|
-
require_relative "../../app/lib/ariadne/view_helper"
|
360
|
-
require File.expand_path("./../../lookbook/config/environment.rb", __dir__)
|
361
|
-
|
362
|
-
YARD::Registry.yardoc_file = ".yardoc"
|
363
|
-
|
364
|
-
require "./app/components/ariadne/component.rb"
|
365
|
-
require "ariadne/view_components"
|
366
|
-
require "yard/docs_helper"
|
367
|
-
require "view_component/base"
|
368
|
-
require "view_component/test_helpers"
|
369
|
-
include(ViewComponent::TestHelpers)
|
370
|
-
include(Ariadne::ViewHelper)
|
371
|
-
include(YARD::DocsHelper)
|
372
|
-
|
373
|
-
Dir["./app/components/ariadne/**/*.rb"].sort.each do |file|
|
374
|
-
puts file
|
375
|
-
require file
|
376
|
-
end
|
377
|
-
|
378
|
-
YARD::Rake::YardocTask.new
|
379
|
-
|
380
|
-
# Custom tags for yard
|
381
|
-
YARD::Tags::Library.define_tag("Accessibility", :accessibility)
|
382
|
-
YARD::Tags::Library.define_tag("Deprecation", :deprecation)
|
383
|
-
YARD::Tags::Library.define_tag("Parameter", :param, :with_types_name_and_default)
|
384
|
-
|
385
|
-
puts "Building YARD documentation."
|
386
|
-
Rake::Task["yard"].execute
|
387
|
-
|
388
|
-
registry = YARD::RegistryStore.new
|
389
|
-
registry.load!(".yardoc")
|
390
|
-
registry
|
391
|
-
end
|
392
|
-
|
393
|
-
def parse_example_tag(tag)
|
394
|
-
name = tag.name
|
395
|
-
description = nil
|
396
|
-
code = nil
|
397
|
-
|
398
|
-
if tag.text.include?("@description")
|
399
|
-
splitted = tag.text.split(/@description|@code/)
|
400
|
-
description = splitted.second.gsub(/^[ \t]{2}/, "").strip
|
401
|
-
code = splitted.last.gsub(/^[ \t]{2}/, "").strip
|
402
|
-
else
|
403
|
-
code = tag.text
|
404
|
-
end
|
405
|
-
|
406
|
-
[name, description, code]
|
407
|
-
end
|
408
|
-
|
409
|
-
def pretty_default_value(tag, component)
|
410
|
-
params = tag.object.parameters.find { |param| [tag.name.to_s, "#{tag.name}:"].include?(param[0]) }
|
411
|
-
default = tag.defaults&.first || params&.second
|
412
|
-
|
413
|
-
return "N/A" unless default
|
414
|
-
|
415
|
-
constant_name = "#{component.name}::#{default}"
|
416
|
-
constant_value = default.safe_constantize || constant_name.safe_constantize
|
417
|
-
|
418
|
-
return pretty_value(default) if constant_value.nil?
|
419
|
-
|
420
|
-
pretty_value(constant_value)
|
421
|
-
end
|
422
|
-
|
423
|
-
def docs_metadata(component)
|
424
|
-
(status_module, component_name) = status_module_and_component_name(component)
|
425
|
-
status_path = status_module.nil? ? "" : "/"
|
426
|
-
status = component.status.to_s
|
427
|
-
|
428
|
-
{
|
429
|
-
title: component_name,
|
430
|
-
component_id: component_name.underscore,
|
431
|
-
status: status.capitalize,
|
432
|
-
source: source_url(component),
|
433
|
-
lookbook: lookbook_url(component),
|
434
|
-
path: "docs/content/components/#{status_path}#{component_name.underscore}.md",
|
435
|
-
example_path: example_path(component),
|
436
|
-
require_js_path: require_js_path(component),
|
437
|
-
}
|
438
|
-
end
|
439
|
-
|
440
|
-
def source_url(component)
|
441
|
-
path = component.name.split("::").map(&:underscore).join("/")
|
442
|
-
|
443
|
-
"https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/#{path}.rb"
|
444
|
-
end
|
445
|
-
|
446
|
-
def lookbook_url(component)
|
447
|
-
path = component.name.split("::").map { |n| n.underscore.dasherize }.join("-")
|
448
|
-
|
449
|
-
"https://ariadne.style/view-components/lookbook/?path=/component/#{path}"
|
450
|
-
end
|
451
|
-
|
452
|
-
def example_path(component)
|
453
|
-
example_path = "../../src/@primer/gatsby-theme-doctocat/components/example"
|
454
|
-
example_path = "../#{example_path}" if status_module?(component)
|
455
|
-
example_path
|
456
|
-
end
|
457
|
-
|
458
|
-
def require_js_path(component)
|
459
|
-
require_js_path = "../../src/@primer/gatsby-theme-doctocat/components/requires-js-flash"
|
460
|
-
require_js_path = "../#{require_js_path}" if status_module?(component)
|
461
|
-
require_js_path
|
462
|
-
end
|
463
|
-
|
464
|
-
def status_module?(component)
|
465
|
-
["Alpha", "Beta"].intersect?(component.name.split("::"))
|
466
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "ast_traverser"
|
4
|
-
|
5
|
-
# :nodoc:
|
6
|
-
class AstProcessor
|
7
|
-
class << self
|
8
|
-
def increment(stats, component, arg_name, value)
|
9
|
-
stats[component][:arguments][arg_name][value] = 0 unless stats[component][:arguments][arg_name][value]
|
10
|
-
stats[component][:arguments][arg_name][value] += 1
|
11
|
-
end
|
12
|
-
|
13
|
-
def process_ast(ast, stats)
|
14
|
-
traverser = AstTraverser.new
|
15
|
-
traverser.walk(ast)
|
16
|
-
|
17
|
-
return if traverser.stats.empty?
|
18
|
-
|
19
|
-
traverser.stats.each do |component, component_info|
|
20
|
-
stats[component] ||= {
|
21
|
-
paths: [],
|
22
|
-
}
|
23
|
-
|
24
|
-
stats[component][:paths] << component_info[:path]
|
25
|
-
stats[component][:paths].uniq!
|
26
|
-
stats[component][:arguments] ||= {}
|
27
|
-
|
28
|
-
component_info[:arguments]&.each do |arg, value|
|
29
|
-
arg_name = arg.to_s
|
30
|
-
stats[component][:arguments][arg_name] ||= {}
|
31
|
-
|
32
|
-
# we want to count each class separately
|
33
|
-
if arg_name == "classes"
|
34
|
-
value.split.each do |val|
|
35
|
-
increment(stats, component, arg_name, val)
|
36
|
-
end
|
37
|
-
else
|
38
|
-
increment(stats, component, arg_name, value)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "ariadne/view_components/statuses"
|
4
|
-
require_relative "../../../app/lib/ariadne/view_helper"
|
5
|
-
|
6
|
-
# :nodoc:
|
7
|
-
class AstTraverser
|
8
|
-
include RuboCop::AST::Traversal
|
9
|
-
|
10
|
-
attr_reader :stats
|
11
|
-
|
12
|
-
def initialize
|
13
|
-
@stats = {}
|
14
|
-
end
|
15
|
-
|
16
|
-
def on_send(node)
|
17
|
-
return super(node) unless component_node?(node)
|
18
|
-
|
19
|
-
name = component_name(node)
|
20
|
-
args = extract_arguments(node, name)
|
21
|
-
|
22
|
-
@stats[name] = { path: node.loc.expression.source_buffer.name }
|
23
|
-
@stats[name][:arguments] = args unless args.empty?
|
24
|
-
|
25
|
-
super(node) # recursively iterate over children
|
26
|
-
end
|
27
|
-
|
28
|
-
def view_helpers
|
29
|
-
@view_helpers ||= ::Ariadne::ViewHelper::HELPERS.keys.map { |key| "ariadne_#{key}".to_sym }
|
30
|
-
end
|
31
|
-
|
32
|
-
def component_node?(node)
|
33
|
-
view_helpers.include?(node.method_name) || (node.method_name == :new && !node.receiver.nil? && ::Ariadne::ViewComponents::STATUSES.key?(node.receiver.const_name))
|
34
|
-
end
|
35
|
-
|
36
|
-
def component_name(node)
|
37
|
-
return node.receiver.const_name if node.method_name == :new
|
38
|
-
|
39
|
-
helper_key = node.method_name.to_s.gsub("ariadne_", "").to_sym
|
40
|
-
Ariadne::ViewHelper::HELPERS[helper_key]
|
41
|
-
end
|
42
|
-
|
43
|
-
def extract_arguments(node, name)
|
44
|
-
args = node.arguments
|
45
|
-
res = {}
|
46
|
-
|
47
|
-
return res if args.empty?
|
48
|
-
|
49
|
-
kwargs = args.last
|
50
|
-
if kwargs.respond_to?(:pairs)
|
51
|
-
res = kwargs.pairs.each_with_object({}) do |pair, h|
|
52
|
-
h.merge!(extract_values(pair))
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
# Heroicon is the only component that accepts positional arguments.
|
57
|
-
res[:icon] = args.first.source if name == "Ariadne::HeroiconComponent" && args.size > 1
|
58
|
-
|
59
|
-
res
|
60
|
-
end
|
61
|
-
|
62
|
-
def extract_values(pair)
|
63
|
-
return { pair.key.value => pair.value.source } unless pair.value.type == :hash
|
64
|
-
|
65
|
-
flatten_pairs(pair, prefix: "#{pair.key.value}-")
|
66
|
-
end
|
67
|
-
|
68
|
-
def flatten_pairs(pair, prefix: "")
|
69
|
-
pair.value.pairs.each_with_object({}) do |value_pair, h|
|
70
|
-
if value_pair.value.type == :hash
|
71
|
-
h.merge!(flatten_pairs(value_pair, prefix: "#{prefix}#{value_pair.key.value}-"))
|
72
|
-
else
|
73
|
-
h["#{prefix}#{value_pair.key.value}"] = value_pair.value.source
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
data/lib/tasks/static.rake
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
namespace :static do
|
4
|
-
desc "Generate static JSON mappings of components for easier loading"
|
5
|
-
task :dump do
|
6
|
-
require File.expand_path("./../../lookbook/config/environment.rb", __dir__)
|
7
|
-
require "ariadne/view_components"
|
8
|
-
# Loads all components for `.descendants` to work properly
|
9
|
-
Dir["./app/components/ariadne/**/*.rb"].sort.each { |file| require file }
|
10
|
-
|
11
|
-
Ariadne::ViewComponents.dump(:statuses)
|
12
|
-
Ariadne::ViewComponents.dump(:constants)
|
13
|
-
Ariadne::ViewComponents.dump(:audited_at)
|
14
|
-
end
|
15
|
-
end
|
data/lib/tasks/test.rake
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "rake/testtask"
|
4
|
-
|
5
|
-
Rake::TestTask.new(:test) do |t|
|
6
|
-
ENV["TZ"] = "Asia/Yerevan"
|
7
|
-
|
8
|
-
t.libs << "test"
|
9
|
-
t.libs << "lib"
|
10
|
-
t.warning = false
|
11
|
-
t.test_files = FileList[ENV["TESTS"] || "test/**/*_test.rb"]
|
12
|
-
end
|
13
|
-
|
14
|
-
Rake::TestTask.new(:bench) do |t|
|
15
|
-
t.libs << "test"
|
16
|
-
t.test_files = FileList["test/benchmarks/**/bench_*.rb"]
|
17
|
-
t.verbose = true
|
18
|
-
t.warning = false
|
19
|
-
end
|
data/lib/yard/docs_helper.rb
DELETED
@@ -1,90 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# :nocov:
|
4
|
-
|
5
|
-
module YARD
|
6
|
-
# Helper methods to use for yard documentation
|
7
|
-
module DocsHelper
|
8
|
-
def one_of(enumerable, lower: false, sort: true)
|
9
|
-
# Sort the array if requested
|
10
|
-
if sort
|
11
|
-
enumerable = enumerable.sort do |a, b|
|
12
|
-
a.instance_of?(b.class) ? a <=> b : a.class.to_s <=> b.class.to_s
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
values =
|
17
|
-
case enumerable
|
18
|
-
when Hash
|
19
|
-
enumerable.map do |key, value|
|
20
|
-
"#{pretty_value(key)} (#{pretty_value(value)})"
|
21
|
-
end
|
22
|
-
else
|
23
|
-
enumerable.map do |key|
|
24
|
-
pretty_value(key)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
prefix = "One of"
|
29
|
-
prefix = prefix.downcase if lower
|
30
|
-
|
31
|
-
"#{prefix} #{values.to_sentence(last_word_connector: ", or ")}."
|
32
|
-
end
|
33
|
-
|
34
|
-
def link_to_accessibility
|
35
|
-
"[Accessibility](#accessibility)"
|
36
|
-
end
|
37
|
-
|
38
|
-
def link_to_classes_docs
|
39
|
-
"[Classes and attributes](/classes-attributes)"
|
40
|
-
end
|
41
|
-
|
42
|
-
def link_to_attributes_docs
|
43
|
-
"[Classes and attributes](/classes-attributes)"
|
44
|
-
end
|
45
|
-
|
46
|
-
def link_to_typography_docs
|
47
|
-
"[Typography](/system-arguments#typography)"
|
48
|
-
end
|
49
|
-
|
50
|
-
def link_to_component(component)
|
51
|
-
(status_module, component_name) = status_module_and_component_name(component)
|
52
|
-
status_path = status_module.nil? ? "" : "/"
|
53
|
-
|
54
|
-
"[#{component_name}](/components/#{status_path}#{component_name.underscore})"
|
55
|
-
end
|
56
|
-
|
57
|
-
def link_to_heroicons
|
58
|
-
"[Heroicon](https://ariadne.style/heroicons/)"
|
59
|
-
end
|
60
|
-
|
61
|
-
def link_to_heading_practices
|
62
|
-
"[Learn more about best heading practices (WAI Headings)](https://www.w3.org/WAI/tutorials/page-structure/headings/)"
|
63
|
-
end
|
64
|
-
|
65
|
-
def status_module_and_short_name(component)
|
66
|
-
name_with_status = component.name.gsub(/Ariadne::|Component/, "")
|
67
|
-
|
68
|
-
m = name_with_status.match(/(?<status>Beta|Alpha|Deprecated)?(?<_colons>::)?(?<name>.*)/)
|
69
|
-
[m[:status]&.downcase, m[:name].gsub("::", "")]
|
70
|
-
end
|
71
|
-
|
72
|
-
def status_module_and_component_name(component)
|
73
|
-
name_with_status = component.name.gsub(/Ariadne::/, "")
|
74
|
-
|
75
|
-
m = name_with_status.match(/(?<status>Beta|Alpha|Deprecated)?(?<_colons>::)?(?<name>.*)/)
|
76
|
-
[m[:status]&.downcase, m[:name].gsub("::", "")]
|
77
|
-
end
|
78
|
-
|
79
|
-
def pretty_value(val)
|
80
|
-
case val
|
81
|
-
when nil
|
82
|
-
"`nil`"
|
83
|
-
when Symbol
|
84
|
-
"`:#{val}`"
|
85
|
-
else
|
86
|
-
"`#{val}`"
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module YARD
|
4
|
-
# YARD Handler to parse `renders_many` calls.
|
5
|
-
class RendersManyHandler < YARD::Handlers::Ruby::Base
|
6
|
-
handles method_call(:renders_many)
|
7
|
-
namespace_only
|
8
|
-
|
9
|
-
process do
|
10
|
-
name = statement.parameters.first.jump(:tstring_content, :ident).source
|
11
|
-
object = YARD::CodeObjects::MethodObject.new(namespace, name)
|
12
|
-
register(object)
|
13
|
-
parse_block(statement.last, owner: object)
|
14
|
-
|
15
|
-
object.dynamic = true
|
16
|
-
object[:renders_many] = true
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module YARD
|
4
|
-
# YARD Handler to parse `renders_one` calls.
|
5
|
-
class RendersOneHandler < YARD::Handlers::Ruby::Base
|
6
|
-
handles method_call(:renders_one)
|
7
|
-
namespace_only
|
8
|
-
|
9
|
-
process do
|
10
|
-
name = statement.parameters.first.jump(:tstring_content, :ident).source
|
11
|
-
object = YARD::CodeObjects::MethodObject.new(namespace, name)
|
12
|
-
register(object)
|
13
|
-
parse_block(statement.last, owner: object)
|
14
|
-
|
15
|
-
object.dynamic = true
|
16
|
-
object[:renders_one] = true
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|