Skip to content

[kyo-data] add Glob - #1856

Merged
DamianReeves merged 6 commits into
mainfrom
glob
Aug 12, 2026
Merged

[kyo-data] add Glob#1856
DamianReeves merged 6 commits into
mainfrom
glob

Conversation

@DamianReeves

@DamianReeves DamianReeves commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add Glob, a compiled and platform-independent matcher for slash-separated paths
  • support *, ?, complete-segment **, character classes, alternatives, and escaping
  • make Glob.ParseError a KyoException with caller Frame context
  • preserve the original pattern through Glob.show and Render[Glob]
  • compile glob"..." literals into a versioned embedded automaton without runtime parsing or compilation

Stack

This is the first PR in the native GitHub stack:

  1. [kyo-data] add Glob #1856, Glob
  2. [kyo-system] extract Path, System, Process, and Command from kyo-core #1857, kyo-system extraction
  3. [kyo-schema-json] JSONL/NDJSON framing, streaming, follow mode, and writing #1852, JSONL in kyo-schema-json
  4. [kyo-schema-json] use ByteSize for JSONL limits and buffers #1854, ByteSize follow-up

Verification

The 27 shared Glob tests pass on JVM, JavaScript, Native, and Wasm, including an externally consumed 4,096-character literal. The JVM bytecode regression test confirms generated literals call GlobLiteral.fromEncodedV1 and do not call Glob.parse. The complete kyo-dataJVM/test suite, the kyo-data README doctest, and scalafmt checks also pass.

…d CHANGELOG entry

The kyo-data README asserted Path.list(glob) and Path.walk(glob) signatures
that do not exist. Rewrite the paragraph to state the integration intent
without asserting a signature. Also add the missing CHANGELOG entry for Glob.
@DamianReeves DamianReeves changed the title [kyo-data] add Glob, a portable compiled pattern for slash-separated paths [kyo-data] add Glob Aug 7, 2026
override def timeout = Duration.fromJava(java.time.Duration.ofMinutes(3))

"allSymbols.count(isGiven) ~= 570 on standard classpath" in {
"allSymbols.count(isGiven) ~= 576 on standard classpath" in {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should change kyo-tasty tests to work with a fixed classpath

@DamianReeves DamianReeves Aug 12, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, that range assertion is going to keep drifting as the classpath changes. Pinning the tests to a fixed classpath means putting together a stable jar set and rewiring TestClasspaths, which feels like its own PR rather than more off-topic weight on this one. I can do it as a follow-up right after this lands, or in this PR if you prefer.

* @see [[Glob.all]]
* @see [[Glob.CaseSensitivity]]
*/
opaque type Glob = Glob.Compiled

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make Glob.Compile the Glob itself?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 8a121cc. Glob is now the final case class directly, with show and both matches overloads as members; the opaque alias and the Compiled wrapper are gone. Construction stays private[kyo], so the public surface is unchanged.

case Result.Failure(error) =>
quotes.reflect.report.errorAndAbort(s"invalid glob at offset ${error.offset}: ${error.reason}")
case Result.Panic(error) => throw error
case Result.Success(glob) => Glob.expression(glob)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice optimization!

* @param reason
* explanation of the invalid syntax
*/
final case class ParseError(offset: Int, reason: String)(using Frame)

@fwbrasil fwbrasil Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when printing to the console, this will show up as just ParseError. Can you rename to GlobParseException? "error" can be confused with Java's Error as well

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to GlobParseException in 8a121cc, hoisted to a top-level type beside Glob so the qualified form does not stutter. kyo-dataJVM and JS suites plus the README doctest are green on the branch.

…ailure

From review: the opaque alias over a private Compiled case class added a level
of indirection with no hiding benefit, since the constructor and fields were
already private[kyo]. Glob is now the final case class directly, carrying show
and the two matches overloads as members, with the same equality and the same
private construction surface.

ParseError becomes GlobParseException, a top-level type beside Glob. A console
line now names the failure unambiguously, and the name no longer invites
confusion with java.lang.Error or the unrelated ParseError types in kyo-parse
and kyo-doctest.
@DamianReeves
DamianReeves merged commit 654618e into main Aug 12, 2026
26 of 27 checks passed
@DamianReeves
DamianReeves deleted the glob branch August 12, 2026 22:39
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