leptris 1.9.8 → 1.9.10
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 +41 -0
- data/README.adoc +21 -2
- data/Rakefile +27 -2
- data/docs/adr/0006-ruby-variant-policy.md +25 -0
- data/lib/leptris/version.rb +1 -1
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4e7dca7e58492747ba0b5843937a7a8a914afa52f4f7271e2b808d1b895a2ded
|
|
4
|
+
data.tar.gz: bf399063035b7cacd20893813e89f85582594ef7644ab8b2ef076772cc40c094
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: df766bafa6dc7d590909f4f6d2a475446115b5d9cd1d57605558654959e699188f1a36329248c653b501e5e432a9a604533e01dd476e9b350a5510be27fa7ca3
|
|
7
|
+
data.tar.gz: c0c8f0f164ceadd0c24d476ca8c4948582e091379f7f976a0fdbfc073d482a97c8a80bf29ad6601f2ad474e0fd4464c5e903cb382b56350be2a6c07a1ef0ecf6
|
data/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,47 @@ 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.10] - 2026-08-26
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **README: Migrating from Nokogiri, caught up to the 1.9.x
|
|
13
|
+
surface** — the notable-differences list now covers the lifetime
|
|
14
|
+
contract (UseAfterFreeError on freed-document reads/mutations),
|
|
15
|
+
readonly mode, recover parsing + last_error_position, searchable
|
|
16
|
+
fragments, receiver-relative css, and expanded-name attribute
|
|
17
|
+
access, each with the migrating reader's context.
|
|
18
|
+
- **Spec organization**: the eight-round perf_surface_spec grab-bag
|
|
19
|
+
splits into one file per concern (seam_and_reads,
|
|
20
|
+
sax_and_query_paths, lifetime_contract, fragment_and_position,
|
|
21
|
+
receiver_relative_css). Suite count unchanged at 274; each file
|
|
22
|
+
is one scannable context.
|
|
23
|
+
|
|
24
|
+
## [1.9.9] - 2026-08-26
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- **CI gates the symbol audit**: the build workflow runs
|
|
29
|
+
`rake compile audit:symbols` before the suite — upstream surface
|
|
30
|
+
drift now fails CI on the PR that first sees it instead of
|
|
31
|
+
relying on someone remembering to run it. The task skips
|
|
32
|
+
gracefully where nm is unavailable (Windows).
|
|
33
|
+
- **benchmark/leptris_vs_nokogiri.rb prints live provenance**
|
|
34
|
+
(library, gem, nokogiri, ruby versions) instead of a frozen
|
|
35
|
+
footer claiming "v0.12.0 / 176 specs".
|
|
36
|
+
- README: the `#search` dispatch description now matches the
|
|
37
|
+
heuristic the code implements (path-prefix → xpath; everything
|
|
38
|
+
else translates as CSS, commas included).
|
|
39
|
+
|
|
40
|
+
### Meta
|
|
41
|
+
|
|
42
|
+
- **ADR 0006** records the ruby-variant packaging policy as
|
|
43
|
+
practiced since 1.9.0: the `ruby` platform gem ships as the
|
|
44
|
+
fallback/source variant without a vendored library, safe under
|
|
45
|
+
the eager-load failure mode (issue #49) — clarifying the 1.9.0
|
|
46
|
+
changelog's "platform variants only" phrasing without rewriting
|
|
47
|
+
history.
|
|
48
|
+
|
|
8
49
|
## [1.9.8] - 2026-08-26
|
|
9
50
|
|
|
10
51
|
### Added
|
data/README.adoc
CHANGED
|
@@ -177,7 +177,7 @@ against a readonly document is legal; mutating the frozen one is not.
|
|
|
177
177
|
`#at_xpath(*exprs)` :: first match (or scalar), like `xpath(*exprs).first`.
|
|
178
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.
|
|
179
179
|
`#at_css(*selectors)` :: first match of `css`.
|
|
180
|
-
`#search(*exprs)` :: dispatches on syntax —
|
|
180
|
+
`#search(*exprs)` :: dispatches on syntax — path-prefixed expressions (`/`, `.`, `..`) go to `xpath`; everything else translates as CSS (comma unions included).
|
|
181
181
|
`#at(*exprs)` :: first match of `search`.
|
|
182
182
|
|
|
183
183
|
[source,ruby]
|
|
@@ -410,7 +410,26 @@ Notable differences:
|
|
|
410
410
|
* `Node#children` includes whitespace text nodes (same as Nokogiri); use
|
|
411
411
|
`#element_children` or `#first_element_child` to skip them.
|
|
412
412
|
* CSS support is intentionally minimal — for advanced selectors, drop to
|
|
413
|
-
`xpath`.
|
|
413
|
+
`xpath`. `css` is receiver-relative (Nokogiri semantics): scoped to
|
|
414
|
+
an element or fragment, document-wide from a Document.
|
|
415
|
+
* `DocumentFragment` is searchable (`fragment.xpath/at_xpath/css/at_css/search`)
|
|
416
|
+
— Nokogiri fragment parity.
|
|
417
|
+
* Expanded-name attribute access: `Element#attribute_ns(uri, local)` /
|
|
418
|
+
`#has_attribute_ns?(uri, local)` — XML Namespaces 1.0 semantics
|
|
419
|
+
(cross-prefix match, nil URI matches no-namespace, xmlns invisible).
|
|
420
|
+
* `Leptris::XML.parse(xml, recover: true)` returns an empty document
|
|
421
|
+
with the failure recorded on the thread-global last error instead of
|
|
422
|
+
raising ParseError — libxml2 `XML_PARSE_RECOVER` semantics. The
|
|
423
|
+
companion `Document#last_error_position` returns `[line, column]`.
|
|
424
|
+
* `Leptris::XML.parse(xml, readonly: true)` (or `Document#readonly!`)
|
|
425
|
+
freezes the document for reading: mutations raise ReadOnlyError, read
|
|
426
|
+
methods memoize aggressively. Faster steady state; no Nokogiri
|
|
427
|
+
equivalent.
|
|
428
|
+
* **Lifetime contract**: a borrowed handle used after the owning
|
|
429
|
+
document has been freed (or GC'd) raises `Leptris::XML::UseAfterFreeError`.
|
|
430
|
+
Nokogiri is silent on this — migrating code that holds Node references
|
|
431
|
+
past Document disposal will see the error; silence-replace-UAF patterns
|
|
432
|
+
from Nokogiri do not apply.
|
|
414
433
|
* No `Nokogiri::HTML` or `Nokogiri::CSS` parser. Leptris is XML-only.
|
|
415
434
|
* No XSLT, no RelaxNG / DTD validation, no schema caching.
|
|
416
435
|
* No built-in JRuby / TruffleRuby support — only CRuby via `ffi`.
|
data/Rakefile
CHANGED
|
@@ -55,9 +55,27 @@ task default: :spec
|
|
|
55
55
|
namespace :audit do
|
|
56
56
|
desc "Fail when ffi.rb attachments and library exports drift"
|
|
57
57
|
task :symbols do
|
|
58
|
+
# nm cannot read MSVC PE export tables (every symbol reports as
|
|
59
|
+
# unexported -> guaranteed false drift), so Windows skips: the
|
|
60
|
+
# darwin/linux CI legs enforce the mirror — any one platform's
|
|
61
|
+
# build of the same C surface suffices.
|
|
62
|
+
if Gem.win_platform?
|
|
63
|
+
puts "audit:symbols: skipped on Windows (PE export tables); " \
|
|
64
|
+
"darwin/linux legs enforce the mirror"
|
|
65
|
+
next
|
|
66
|
+
end
|
|
67
|
+
# Probe nm without a shell: the multi-arg system() execs
|
|
68
|
+
# directly, so there is no which/redirect syntax to be
|
|
69
|
+
# platform-hostile. File::NULL is NUL where it must be; a
|
|
70
|
+
# missing binary is falsy either way (ENOENT rescue belts the
|
|
71
|
+
# older spawn behavior).
|
|
72
|
+
unless nm_available?
|
|
73
|
+
puts "audit:symbols: skipped (nm unavailable on this platform)"
|
|
74
|
+
next
|
|
75
|
+
end
|
|
58
76
|
lib = Dir.glob("lib/libleptris.{dylib,so,dll}").first
|
|
59
|
-
unless lib
|
|
60
|
-
abort "audit:symbols: vendored library
|
|
77
|
+
unless lib
|
|
78
|
+
abort "audit:symbols: vendored library not found — run rake compile"
|
|
61
79
|
end
|
|
62
80
|
exported = `nm -gU #{lib}`
|
|
63
81
|
.lines.map { |l| l.split[2] }.compact
|
|
@@ -82,6 +100,13 @@ namespace :audit do
|
|
|
82
100
|
abort "audit:symbols: drift detected"
|
|
83
101
|
end
|
|
84
102
|
end
|
|
103
|
+
|
|
104
|
+
# @api private
|
|
105
|
+
def nm_available?
|
|
106
|
+
system("nm", "--version", out: File::NULL, err: File::NULL)
|
|
107
|
+
rescue Errno::ENOENT
|
|
108
|
+
false
|
|
109
|
+
end
|
|
85
110
|
end
|
|
86
111
|
|
|
87
112
|
require "rubygems/package_task"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# ADR 0006: the ruby-platform variant ships as the fallback, unvendored
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
The 1.9.0-era CHANGELOG said "never publishes ruby-platform releases
|
|
5
|
+
without the vendored library — platform variants only", and an early
|
|
6
|
+
fix removed the `gem:native:any` task. The 1.9.0 lockstep restored
|
|
7
|
+
the `ruby` matrix entry deliberately, and every release since has
|
|
8
|
+
published the variant — practice contradicting the recorded policy.
|
|
9
|
+
|
|
10
|
+
## Decision
|
|
11
|
+
The `ruby`-platform gem ships as the fallback/source variant WITHOUT
|
|
12
|
+
a vendored library, by design. It is safe because library resolution
|
|
13
|
+
is eager (issue #49): on a machine without a usable libleptris the
|
|
14
|
+
gem fails at `require` with the actionable remedy (install the
|
|
15
|
+
platform-specific variant or set LEPTRIS_LIB_PATH) instead of deep
|
|
16
|
+
inside Document.parse. Bundler prefers platform-specific gems
|
|
17
|
+
wherever they exist (9 of 10 published variants are precompiled);
|
|
18
|
+
the ruby variant serves source installs and exotic platforms that
|
|
19
|
+
accept providing their own library.
|
|
20
|
+
|
|
21
|
+
## Consequences
|
|
22
|
+
Do not re-propose removing the `platform: any` release leg without
|
|
23
|
+
new evidence that bundler misresolves it in practice. A future
|
|
24
|
+
change to the eager-load behavior (ADR 0005 ordering aside) must
|
|
25
|
+
keep the ruby variant failing loudly at require time.
|
data/lib/leptris/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
@@ -74,6 +74,7 @@ files:
|
|
|
74
74
|
- docs/adr/0003-readonly-memoization-pattern.md
|
|
75
75
|
- docs/adr/0004-lifetime-guard.md
|
|
76
76
|
- docs/adr/0005-autoload-manifest-ordering.md
|
|
77
|
+
- docs/adr/0006-ruby-variant-policy.md
|
|
77
78
|
- leptris.gemspec
|
|
78
79
|
- lib/leptris.rb
|
|
79
80
|
- lib/leptris/version.rb
|