Skip to content

Merge upstream master into the fork, and keep json below 3 for old Rails - #5

Merged
njakobsen merged 11 commits into
masterfrom
sync-upstream-master
Oct 6, 2026
Merged

njakobsen merged 11 commits into
masterfrom
sync-upstream-master

Conversation

@njakobsen

@njakobsen njakobsen commented Oct 6, 2026 •

Copy link
Copy Markdown
Member

Summary

Brings the fork's master up to upstream master (80f246b7). The merge commit's tree is identical to upstream's; the second commit adds the json pin below.

A second commit pins json < 3 in sunspot_rails' Rails 6.1 and 7.0 appraisals. CI now resolves json 3.0.2, and under it every example in the sunspot_rails JSON-update jobs on Ruby 3.0–3.3 failed in Sunspot.remove_all! with ArgumentError: unknown keyword: quirks_mode from RSolr's to_json. Upstream's last green run on this tree (2026-08-18) predates json 3, so a fresh run of upstream master would likely fail the same way (not checked).

Glint and stolo_connect pin the fork by revision, so nothing changes for them until their lockfiles move. #4 is stacked on this branch so its CI runs with these fixes.

Test plan

  • Tree equals upstream master's (git rev-parse HEAD^{tree} matches sunspot/master^{tree}). Upstream's CI on 80f246b7 passed.
  • CI on bbe8da4: 56 jobs pass. On the merge commit alone, the four sunspot_rails JSON-update jobs failed with the quirks_mode error and everything else passed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TAYgm5SknHTiRNTgGA6LBY

s4na and others added 11 commits December 27, 2024 13:06
* Fix: Update RSpec test to properly use `include` matcher with expected values

The test was updated to explicitly map `value` from the `groups` collection
and use the `include` matcher with specific arguments ("Title1" and "Title2").
This resolves an `ArgumentError` caused by passing a block to `include`.

## Error Details

```
Failures:

  1) field grouping allows grouping by a field
     Failure/Error: expect(search.group(:title).groups).to include { |g| g.value == "Title1" }

     ArgumentError:
       include() is not supported, please supply an argument
     # ./spec/integration/field_grouping_spec.rb:22:in 'block (2 levels) in <top (required)>'

Finished in 7.29 seconds (files took 0.29196 seconds to load)
1426 examples, 1 failure, 1 pending

Failed examples:

rspec ./spec/integration/field_grouping_spec.rb:17 # field grouping allows grouping by a field
```

* Add Ruby 3.4 to CI
Included examples of emptying the search index
This commit addresses multiple compatibility issues to ensure Sunspot works
seamlessly across Ruby versions 2.5 through 3.5+:

## Changes

1. **Standard Library Dependencies**
   - Add `ostruct` and `logger` as explicit runtime dependencies
   - These were extracted from Ruby's stdlib in 3.5+ and now require explicit gems
   - Preload in Rails spec helper to prevent autoload race conditions

2. **Ruby 2.5 Compatibility**
   - Constrain `psych` to < 4.0 for Ruby 2.5 environments
   - Psych 4.0 dropped Ruby 2.5 support, causing LoadError failures

3. **RDoc Task Loading**
   - Improve rdoc task loading with proper fallback mechanism
   - Support both modern (`rdoc/task`) and legacy (`rake/rdoctask`) APIs
   - Gracefully handle missing RDoc without breaking rake tasks

4. **CI Stability**
   - Fix flaky test in Ruby 2.7 with JSON format
   - Add targeted sleep to ensure Solr commit completes before search

## Testing

All changes have been verified across the full Ruby version matrix:
- Ruby 2.5, 2.6, 2.7, 3.0, 3.1, 3.2, 3.3, 3.4, and head
- Both JSON and XML update formats
- All three gems: sunspot, sunspot_rails, and sunspot_solr

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
`Restriction::Between` writes every range as `[a TO b]`, so a Ruby range built with `...` quietly includes the endpoint it was written to exclude. An exclusive-end range now emits Solr's half-open form, `[a TO b}`.

This matters wherever the end of one range is the start of the next — consecutive date ranges being the common case — where the shared boundary would otherwise match in both.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Emit half-open Solr ranges for exclusive-end Ruby ranges
`indexing_spec.rb`'s "should correctly remove by model instance" and "should correctly delete by ID" index a `Post` titled 'test post', delete it, and assert that a search for that title returns nothing. Neither clears the index first. `scoped_search_spec.rb`'s "prefix searching" block indexes its own `Post` titled 'test post' and, following the suite's clean-before convention, leaves it there. The specs run in randomized order, so an ordering that puts the prefix example last before the delete examples leaves that document in the index for them to find, and both fail on a document neither of them indexed.

Running the prefix example and the two delete examples in that order reproduces the failure every time; the two delete examples pass 25 runs out of 25 in isolation.

Instead of sleeping after the delete, the two examples now open with `Sunspot.remove_all!`, as "removes documents by query" three lines below them already does. The sleep could not have helped: `remove!` and `remove_by_id!` call `commit`, which posts a hard commit, and a Solr commit defaults to `waitSearcher=true`, so the new searcher is registered before the request returns. Raising the sleep to a full second does not prevent the failure.

Refs sunspot#1053

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fix the flaky indexing delete specs by isolating them
Solr 7.7 added `facet.matches`, which restricts the values a field facet returns to those matching a regular expression. Sunspot had no way to send it, so narrowing a facet to a subset of its values meant faceting on all of them and filtering the rows in Ruby, which pays for the full term enumeration and applies `:limit` and `:sort` to the unnarrowed set.

`facet :title, :matches => 'Test.*'` now emits `f.title_ss.facet.matches`, alongside the other per-facet parameters `AbstractFieldFacet` already qualifies with `f.<key>.`. Qualifying it is what keeps the pattern on the facet it was given to. Solr's unqualified `facet.matches` applies to every facet in the request, which empties the rows of the other facets when they are string fields, and fails the request outright with `BytesRef term filters (facet.matches, facet.contains, facet.excludeTerms) are not supported on numeric types` when any of them is numeric.

The pattern is a Java regular expression matched against the whole indexed value, so `Rings` matches the value `Rings` and not the value `Lord of the Rings`.

The specs assert the emitted parameters rather than the returned rows, because `sunspot_solr` bundles Solr 5.3.1 and it ignores `facet.matches`. The behaviour was verified end to end against Solr 8.11.4.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add a :matches option to filter facet values by regular expression
The fork's `master` predates upstream's CI fixes (sunspot#1051, Ruby 3.4+ support and the `sunspot_rails` / rdoc / RSpec fixes), so every branch cut from it fails CI on `field_grouping_spec.rb`, `faceting_spec.rb`, and the `sunspot_rails` and `ruby-head` jobs. Upstream has also merged the reworked versions of the fork's two own commits, exclusive-end range restrictions (sunspot#1054) and the `:matches` facet option (sunspot#1056), along with sunspot#1055.

Conflicts are resolved to upstream's version throughout, so the fork's tree now equals upstream `master`. The `:matches` option keeps its name and is sent per field as `f.<field>.facet.matches` instead of a global `facet.matches`; the exclusive-end range code differs from the fork's only in whitespace.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI now resolves json 3.0.2, and in the `sunspot_rails` jobs on Ruby 3.0–3.3 with JSON updates, which run the Rails 6.1 and 7.0 appraisals, every example failed in `Sunspot.remove_all!` with `ArgumentError: unknown keyword: quirks_mode` from RSolr's `to_json`. The XML-update jobs don't serialize with `to_json` and pass. Upstream's last green run on this tree (2026-08-18) predates json 3.

The Rails 6.1 and 7.0 appraisals now require `json < 3`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@njakobsen njakobsen changed the title Merge upstream master into the fork Merge upstream master into the fork, and keep json below 3 for old Rails Oct 6, 2026
@njakobsen
njakobsen marked this pull request as ready for review October 6, 2026 07:53
@njakobsen
njakobsen merged commit 44308e2 into master Oct 6, 2026
57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants