leptris 1.9.7 → 1.9.8
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 +18 -0
- data/CLAUDE.md +3 -2
- data/README.adoc +8 -2
- data/Rakefile +35 -0
- data/lib/leptris/version.rb +1 -1
- data/lib/leptris/xml/ffi.rb +18 -0
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8f306f9bc45d304b82c3db1ac2936dcc0d708b21d2caf595e4a9484da5c6b48a
|
|
4
|
+
data.tar.gz: ce9b04f6f1e91e6dffd1ff68ce70967b8b2bcff8351132db2f3312e4b534e803
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 40618f16214157768b018c774816f738a8cbce00e757286822a69f22f71413605c165448a22644b1ff5cc66a387ce63d6e2c496167b8049f2e80ab7cdf124582
|
|
7
|
+
data.tar.gz: f3c5d00e54f051510d76db44582806252ccf84091c9c9eb11915fc43675282721f4224fada0331f45616250be411362f981d545fb5de47bfcaadfaf09a4954bb
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,24 @@ All notable changes to Leptris will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.9.8] - 2026-08-26
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **`rake audit:symbols`**: the lockstep drift detector as an
|
|
13
|
+
executable step — `nm -gU` on the vendored library vs the ffi.rb
|
|
14
|
+
attach list, failing with both directions of drift (ADR 0001's
|
|
15
|
+
enforcement arm; previously prose plus ad-hoc pipelines).
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- ffi.rb attaches the five header-declared exports past cleanups
|
|
20
|
+
had dropped (element_children, serialize_document,
|
|
21
|
+
xpath_ns_set_add, xpath_result_get, xpath_result_get_nodes) —
|
|
22
|
+
mirror-only, supersession noted inline. The audit now runs green:
|
|
23
|
+
**224/224 symbols in lockstep**. Pull-attribute batch fetch asked
|
|
24
|
+
upstream (leptris/leptris#562).
|
|
25
|
+
|
|
8
26
|
## [1.9.7] - 2026-08-26
|
|
9
27
|
|
|
10
28
|
### Added
|
data/CLAUDE.md
CHANGED
|
@@ -91,6 +91,7 @@ lib/leptris/xml/css_to_xpath.rb — minimal CSS translation
|
|
|
91
91
|
check both before proposing refactors; they exist so reviews
|
|
92
92
|
stop re-deriving settled questions.
|
|
93
93
|
- libleptris public headers (`src/include/leptris/*.h`) are the
|
|
94
|
-
contract; when symbols change, bump lockstep and
|
|
95
|
-
|
|
94
|
+
contract; when symbols change, bump lockstep and run
|
|
95
|
+
`rake audit:symbols` (attached == exported on the vendored
|
|
96
|
+
library; fails listing both directions of drift).
|
|
96
97
|
- Upstream issues worth tracking live at leptris/leptris.
|
data/README.adoc
CHANGED
|
@@ -169,12 +169,13 @@ against a readonly document is legal; mutating the frozen one is not.
|
|
|
169
169
|
|
|
170
170
|
== Searching: XPath and CSS
|
|
171
171
|
|
|
172
|
-
`Document` and `
|
|
172
|
+
`Document`, `Element`, and `DocumentFragment` (via
|
|
173
|
+
`Leptris::XML::Searchable`) support:
|
|
173
174
|
|
|
174
175
|
[horizontal]
|
|
175
176
|
`#xpath(*exprs)` :: evaluate XPath; returns `NodeSet`, `true`/`false`, `Float`, or `String` depending on the expression.
|
|
176
177
|
`#at_xpath(*exprs)` :: first match (or scalar), like `xpath(*exprs).first`.
|
|
177
|
-
`#css(*selectors)` :: minimal CSS-to-XPath translation, then `xpath`.
|
|
178
|
+
`#css(*selectors)` :: minimal CSS-to-XPath translation, then `xpath`. Receiver-relative (Nokogiri semantics): scoped to the element or fragment, document-wide from a Document.
|
|
178
179
|
`#at_css(*selectors)` :: first match of `css`.
|
|
179
180
|
`#search(*exprs)` :: dispatches on syntax — `/`-prefixed or `,`-separated → `xpath`, otherwise `css`.
|
|
180
181
|
`#at(*exprs)` :: first match of `search`.
|
|
@@ -190,6 +191,11 @@ doc.at_xpath("string(//book[1]/@id)") # => "b1"
|
|
|
190
191
|
doc.css("book[lang='en'] title") # => NodeSet[<title>Refactoring</title>]
|
|
191
192
|
doc.at_css("book#b1 title") # => <title>Refactoring</title> (id selector)
|
|
192
193
|
doc.css("book:first-child") # first <book>
|
|
194
|
+
|
|
195
|
+
# css is receiver-relative: scoped to the receiver, not the document
|
|
196
|
+
doc.root.at_css("book").css("title") # titles under THAT book only
|
|
197
|
+
frag = doc.fragment("<a x='1'><n/></a>")
|
|
198
|
+
frag.css("a > n") # searches the fragment
|
|
193
199
|
----
|
|
194
200
|
|
|
195
201
|
XPath result type follows XPath 1.0 semantics:
|
data/Rakefile
CHANGED
|
@@ -49,6 +49,41 @@ task spec: :compile unless ENV.key?("LEPTRIS_LIB_PATH")
|
|
|
49
49
|
|
|
50
50
|
task default: :spec
|
|
51
51
|
|
|
52
|
+
# Lockstep drift detector (ADR 0001): ffi.rb mirrors the public
|
|
53
|
+
# header, so attached == exported must hold on the vendored library.
|
|
54
|
+
# Run after `rake compile` and before any lockstep release.
|
|
55
|
+
namespace :audit do
|
|
56
|
+
desc "Fail when ffi.rb attachments and library exports drift"
|
|
57
|
+
task :symbols do
|
|
58
|
+
lib = Dir.glob("lib/libleptris.{dylib,so,dll}").first
|
|
59
|
+
unless lib && system("which nm > /dev/null 2>&1")
|
|
60
|
+
abort "audit:symbols: vendored library or nm not found — run rake compile"
|
|
61
|
+
end
|
|
62
|
+
exported = `nm -gU #{lib}`
|
|
63
|
+
.lines.map { |l| l.split[2] }.compact
|
|
64
|
+
.map { |n| n.sub(/\A_/, "") }
|
|
65
|
+
.select { |n| n.start_with?("leptris_") }
|
|
66
|
+
.map { |n| n.sub(/\Aleptris_/, "") }.sort
|
|
67
|
+
attached = File.read("lib/leptris/xml/ffi.rb")
|
|
68
|
+
.scan(/attach_function :leptris_([a-z_0-9]+)/).flatten.sort
|
|
69
|
+
unattached = exported - attached
|
|
70
|
+
unexported = attached - exported
|
|
71
|
+
unless unattached.empty?
|
|
72
|
+
puts "exported but NOT attached (upstream surface drift):"
|
|
73
|
+
unattached.each { |s| puts " leptris_#{s}" }
|
|
74
|
+
end
|
|
75
|
+
unless unexported.empty?
|
|
76
|
+
puts "attached but NOT exported (stale attachment):"
|
|
77
|
+
unexported.each { |s| puts " leptris_#{s}" }
|
|
78
|
+
end
|
|
79
|
+
if unattached.empty? && unexported.empty?
|
|
80
|
+
puts "audit:symbols: #{attached.length}/#{exported.length} symbols in lockstep"
|
|
81
|
+
else
|
|
82
|
+
abort "audit:symbols: drift detected"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
52
87
|
require "rubygems/package_task"
|
|
53
88
|
|
|
54
89
|
desc "Build the pure-Ruby gem"
|
data/lib/leptris/version.rb
CHANGED
data/lib/leptris/xml/ffi.rb
CHANGED
|
@@ -173,6 +173,10 @@ module Leptris
|
|
|
173
173
|
# count-only query returning the TOTAL across every child kind.
|
|
174
174
|
attach_function :leptris_node_children,
|
|
175
175
|
[:leptris_node_ref, :pointer, :size_t], :size_t
|
|
176
|
+
# Element-only batch; mirror-only — fetch_children rides the
|
|
177
|
+
# all-kind node_children above.
|
|
178
|
+
attach_function :leptris_element_children,
|
|
179
|
+
[:leptris_element, :pointer, :size_t], :size_t
|
|
176
180
|
attach_function :leptris_node_as_element,
|
|
177
181
|
[:leptris_node_ref], :leptris_element
|
|
178
182
|
attach_function :leptris_element_as_node,
|
|
@@ -402,6 +406,12 @@ module Leptris
|
|
|
402
406
|
# which (element / synthetic attribute / text / other).
|
|
403
407
|
attach_function :leptris_xpath_result_node_kind,
|
|
404
408
|
[:leptris_xpath_result, :size_t], :int
|
|
409
|
+
# Pre-_ex variants, superseded by xpath_result_get_nodes_ex /
|
|
410
|
+
# xpath_result_get_node; mirror-only (ADR 0001).
|
|
411
|
+
attach_function :leptris_xpath_result_get,
|
|
412
|
+
[:leptris_xpath_result, :size_t], :leptris_element
|
|
413
|
+
attach_function :leptris_xpath_result_get_nodes,
|
|
414
|
+
[:leptris_xpath_result, :pointer, :size_t], :size_t
|
|
405
415
|
attach_function :leptris_xpath_result_get_node,
|
|
406
416
|
[:leptris_xpath_result, :size_t], :leptris_node_ref
|
|
407
417
|
attach_function :leptris_xpath_result_node_name,
|
|
@@ -447,6 +457,10 @@ module Leptris
|
|
|
447
457
|
[:leptris_xpath_ns_set], :void
|
|
448
458
|
# One-call constructor: flat array of 2*pair_count alternating
|
|
449
459
|
# prefix/URI strings.
|
|
460
|
+
# Per-pair add; superseded by ns_set_new_from_pairs (one call);
|
|
461
|
+
# mirror-only (ADR 0001).
|
|
462
|
+
attach_function :leptris_xpath_ns_set_add,
|
|
463
|
+
[:leptris_xpath_ns_set, :string, :string], :leptris_status
|
|
450
464
|
attach_function :leptris_xpath_ns_set_new_from_pairs,
|
|
451
465
|
[:pointer, :size_t], :leptris_xpath_ns_set
|
|
452
466
|
attach_function :leptris_xpath_eval_ns,
|
|
@@ -507,6 +521,10 @@ module Leptris
|
|
|
507
521
|
|
|
508
522
|
attach_function :leptris_document_serialize,
|
|
509
523
|
[:leptris_document, :pointer], :pointer
|
|
524
|
+
# Deprecated automatic-options alias (header: prefer
|
|
525
|
+
# leptris_document_serialize); mirror-only.
|
|
526
|
+
attach_function :leptris_serialize_document,
|
|
527
|
+
[:leptris_document], :pointer
|
|
510
528
|
# libleptris >= 1.9.0: caller-buffer serialization with options
|
|
511
529
|
# (leptris#541). buf=NULL is a size query; the size-query +
|
|
512
530
|
# fill pair reuses one serialization through a per-document
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: leptris
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.9.
|
|
4
|
+
version: 1.9.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ffi
|