poetry-core 0.1.2 → 0.1.3
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 +7 -0
- data/lib/poetry/core/check.rb +43 -6
- data/lib/poetry/core/host_components.rb +34 -0
- data/lib/poetry/core/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 74940c713a7f81772d930f9581313847ec1a4044f36c3b31774efafd31bd07ef
|
|
4
|
+
data.tar.gz: 9e869c5574bef206ee03a998d31beda8cc10cf6f70e429134fb80b70fec8e2be
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6bfcc4296038b8766014f1ed52cda1e9c365a9242aabcc0f8bac7a864e63c64a01438ec58d46c48ed1525d0191f7d1e0e9b4826932f996cb0184de123a19f856
|
|
7
|
+
data.tar.gz: c5c56a37ae235c3d88b155a9197138c9f583187814431d957f78efb430c8e925a86fc039111df305fec8d00b90e0b4cfe46eb897eca3415e8bc97b7d0182b670
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.3] - 2026-09-13
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- `poetry check` no longer flags `with_trigger(compose: true) do |wiring|` (any composed slot) as a yieldless block: `compose: true` is the slot's other contract, and the setter yields the wiring for the caller's own control.
|
|
8
|
+
- The app's own `poetry_*` helper methods are valid names for `poetry check` and the MCP `check` tool: `Poetry::Core::HostComponents.helper_methods` reads `def poetry_*` from `app/helpers` boot-free (the adapter `poetry:pagination` copies in, a wrapper the host wrote), and such a call is linted for its wiring only, since no registry describes its options or its block. A registry helper of the same name keeps the registry's contract.
|
|
9
|
+
|
|
3
10
|
## [0.1.2] - 2026-09-13
|
|
4
11
|
|
|
5
12
|
### Added
|
data/lib/poetry/core/check.rb
CHANGED
|
@@ -71,8 +71,8 @@ module Poetry
|
|
|
71
71
|
# rgb(...)) - a url(#fragment) is not a color.
|
|
72
72
|
STYLE_COLOR = /(?<!url\()#\h{3,8}\b|\b(?:#{COLOR_FUNCTIONS.join("|")})\([^)]*\)/i
|
|
73
73
|
|
|
74
|
-
def self.from_registry(root, helpers: nil, icon_names: nil)
|
|
75
|
-
from_registries([root], helpers: helpers, icon_names: icon_names)
|
|
74
|
+
def self.from_registry(root, helpers: nil, icon_names: nil, host_helpers: nil)
|
|
75
|
+
from_registries([root], helpers: helpers, icon_names: icon_names, host_helpers: host_helpers)
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
# A host catalog spans every installed poetry gem (ui + charts): a
|
|
@@ -82,7 +82,7 @@ module Poetry
|
|
|
82
82
|
# host_registry: the app's own components (HostComponents.registry),
|
|
83
83
|
# merged in beside the gem registries - their declared helpers join
|
|
84
84
|
# the valid set and their contracts are checked like any other.
|
|
85
|
-
def self.from_registries(roots, helpers: nil, icon_names: nil, host_registry: nil)
|
|
85
|
+
def self.from_registries(roots, helpers: nil, icon_names: nil, host_registry: nil, host_helpers: nil)
|
|
86
86
|
payloads = roots.map do |root|
|
|
87
87
|
YAML.load_file(Pathname.new(root).join(Registry::RELATIVE_PATH), aliases: true)
|
|
88
88
|
end
|
|
@@ -96,7 +96,8 @@ module Poetry
|
|
|
96
96
|
helpers: helpers,
|
|
97
97
|
helper_entries: payloads.map { |payload| payload["helpers"] || {} }.reduce({}, :merge),
|
|
98
98
|
icon_names: icon_names,
|
|
99
|
-
helper_args: helper_args
|
|
99
|
+
helper_args: helper_args,
|
|
100
|
+
host_helpers: host_helpers)
|
|
100
101
|
end
|
|
101
102
|
|
|
102
103
|
# helpers: the FULL set of valid poetry_* helper method names (from
|
|
@@ -110,11 +111,16 @@ module Poetry
|
|
|
110
111
|
# helpers (poetry_input_group_addon align: et al). icon_names: the
|
|
111
112
|
# active icon set's valid names - when given, icon-formatted option
|
|
112
113
|
# values are checked for membership, not just shape.
|
|
113
|
-
def initialize(components, helpers: nil, helper_entries: nil, icon_names: nil, helper_args: nil
|
|
114
|
+
def initialize(components, helpers: nil, helper_entries: nil, icon_names: nil, helper_args: nil,
|
|
115
|
+
host_helpers: nil)
|
|
114
116
|
@components = components
|
|
115
117
|
@helper_entries = helper_entries || {}
|
|
116
118
|
@helper_args = helper_args || {}
|
|
117
119
|
@icon_names = icon_names&.to_set(&:to_s)
|
|
120
|
+
# The app's own poetry_* helper METHODS (HostComponents.helper_methods:
|
|
121
|
+
# a pagination adapter, a wrapper of the host's own) - valid by
|
|
122
|
+
# name, contracts their own.
|
|
123
|
+
@host_helpers = (host_helpers || []).to_set(&:to_s)
|
|
118
124
|
# helper name -> registry path: poetry_ + the path under the gem
|
|
119
125
|
# namespace (poetry/ui/command/dialog -> poetry_command_dialog,
|
|
120
126
|
# avoiding the last-segment collision with poetry/ui/dialog). The
|
|
@@ -131,6 +137,7 @@ module Poetry
|
|
|
131
137
|
end.to_h
|
|
132
138
|
@helper_by_path = @path_by_helper.invert
|
|
133
139
|
@helper_names = ((helpers&.map(&:to_s) || @path_by_helper.keys) + @helper_entries.keys).to_set
|
|
140
|
+
@helper_names.merge(@host_helpers)
|
|
134
141
|
end
|
|
135
142
|
|
|
136
143
|
attr_reader :icon_names
|
|
@@ -138,6 +145,15 @@ module Poetry
|
|
|
138
145
|
def helper_names = @helper_names.to_a
|
|
139
146
|
|
|
140
147
|
def helper?(name) = @helper_names.include?(name)
|
|
148
|
+
|
|
149
|
+
# A helper method the app defines under the prefix and no registry
|
|
150
|
+
# describes: the name is valid, its contract is the app's own. A
|
|
151
|
+
# registry entry of the same name (a gem helper the app redefines)
|
|
152
|
+
# keeps the registry's contract.
|
|
153
|
+
def host_helper?(name)
|
|
154
|
+
@host_helpers.include?(name) && !@path_by_helper.key?(name) && !@helper_entries.key?(name)
|
|
155
|
+
end
|
|
156
|
+
|
|
141
157
|
def path_for(helper) = @path_by_helper[helper]
|
|
142
158
|
# The helper that renders a registry path (the declared name, or the
|
|
143
159
|
# poetry_ convention).
|
|
@@ -428,6 +444,14 @@ module Poetry
|
|
|
428
444
|
message: "no poetry component #{helper}", line: line, suggestion: suggestion)]
|
|
429
445
|
end
|
|
430
446
|
|
|
447
|
+
# A helper method of the app's own under the prefix (a pagination
|
|
448
|
+
# adapter poetry:pagination copied in, a wrapper the host wrote):
|
|
449
|
+
# no registry knows its options or whether it yields, so only the
|
|
450
|
+
# wiring rules apply.
|
|
451
|
+
if @catalog.host_helper?(helper)
|
|
452
|
+
return passthrough_findings(keyword_pairs(call), base_line) + data_findings(call, base_line, helper)
|
|
453
|
+
end
|
|
454
|
+
|
|
431
455
|
# A valid helper with no component mapping (group / provider / item
|
|
432
456
|
# wrapper): its registry-declared value contracts still check, and
|
|
433
457
|
# NO wrapper yields anything to its block (a roster invariant) - a
|
|
@@ -854,7 +878,7 @@ module Poetry
|
|
|
854
878
|
# WITHOUT a block (Carousel with_item).
|
|
855
879
|
def setter_block_findings(entry, slot_name, call, line)
|
|
856
880
|
findings = []
|
|
857
|
-
if (entry["yieldless"] || []).include?(slot_name) && block_param_name(call)
|
|
881
|
+
if (entry["yieldless"] || []).include?(slot_name) && !composed?(call) && block_param_name(call)
|
|
858
882
|
findings << Finding.new(rule: "yieldless-block", severity: :error,
|
|
859
883
|
message: "with_#{slot_name} yields nothing to its block - the param " \
|
|
860
884
|
"will be nil; remove it and write the content directly",
|
|
@@ -924,6 +948,19 @@ module Poetry
|
|
|
924
948
|
end
|
|
925
949
|
end
|
|
926
950
|
|
|
951
|
+
# A setter called with `compose: true` is the slot's other
|
|
952
|
+
# contract: it yields the wiring for the caller's own control, so
|
|
953
|
+
# the block param is the point, not a mistake.
|
|
954
|
+
def composed?(call)
|
|
955
|
+
hash = call.arguments&.arguments&.find { |argument| argument.is_a?(Prism::KeywordHashNode) }
|
|
956
|
+
return false unless hash
|
|
957
|
+
|
|
958
|
+
hash.elements.any? do |element|
|
|
959
|
+
element.is_a?(Prism::AssocNode) && element.key.respond_to?(:unescaped) &&
|
|
960
|
+
element.key.unescaped == "compose" && element.value.is_a?(Prism::TrueNode)
|
|
961
|
+
end
|
|
962
|
+
end
|
|
963
|
+
|
|
927
964
|
# [key_string, literal_value_or_nil, line] per keyword argument.
|
|
928
965
|
def keyword_pairs(call)
|
|
929
966
|
hash = call.arguments&.arguments&.find { |argument| argument.is_a?(Prism::KeywordHashNode) }
|
|
@@ -127,6 +127,40 @@ module Poetry
|
|
|
127
127
|
end.uniq.sort
|
|
128
128
|
end
|
|
129
129
|
|
|
130
|
+
# The app's own `poetry_*` view helper METHODS, boot-free: a source
|
|
131
|
+
# scan of app/helpers for instance-method definitions under the
|
|
132
|
+
# prefix (the adapter `poetry:pagination` copies in, a wrapper the
|
|
133
|
+
# host wrote). They join `poetry check`'s valid names - the MCP
|
|
134
|
+
# server's check tool and `bin/rails poetry:check` alike - with
|
|
135
|
+
# contracts of their own, which no registry describes.
|
|
136
|
+
#
|
|
137
|
+
# @param root [String, Pathname] the app root
|
|
138
|
+
# @return [Array<String>] sorted, unique
|
|
139
|
+
def helper_methods(root:)
|
|
140
|
+
Dir.glob(Pathname.new(root).join("app/helpers/**/*.rb").to_s).flat_map do |file|
|
|
141
|
+
result = Prism.parse(File.read(file))
|
|
142
|
+
result.success? ? HelperMethods.new.tap { |finder| result.value.accept(finder) }.names : []
|
|
143
|
+
end.uniq.sort
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# The `def poetry_*` instance methods, from the syntax tree - a
|
|
147
|
+
# singleton method, a mention in a string or a comment is not one.
|
|
148
|
+
class HelperMethods < Prism::Visitor
|
|
149
|
+
PREFIX = "poetry_"
|
|
150
|
+
|
|
151
|
+
attr_reader :names
|
|
152
|
+
|
|
153
|
+
def initialize
|
|
154
|
+
super
|
|
155
|
+
@names = []
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def visit_def_node(node)
|
|
159
|
+
@names << node.name.to_s if node.receiver.nil? && node.name.start_with?(PREFIX)
|
|
160
|
+
super
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
130
164
|
# The `helper :name` / `helper("name")` calls in class bodies, from
|
|
131
165
|
# the syntax tree - a mention inside a string, a heredoc or a comment
|
|
132
166
|
# is not a declaration.
|
data/lib/poetry/core/version.rb
CHANGED