From d57d784aa30814a970d852b5b8361d5aeb9f3b7f Mon Sep 17 00:00:00 2001 From: Anton-4 <17049058+Anton-4@users.noreply.github.com> Date: Thu, 1 Oct 2026 23:07:23 +0200 Subject: [PATCH] Update examples to basic-cli 0.23.0 and Roc nightly-2026-10-01-a932c65 basic-cli 0.23.0 no longer passes the program name in argv, so examples read user arguments directly. Also apply formatter output from the new nightly and write bidi control characters in tests/apps/bidi as \u(...) escapes, which the compiler now requires. Co-Authored-By: Claude Sonnet 5.5 --- .roc-version | 2 +- examples/CliArgs.roc | 2 +- examples/bidi-analysis.roc | 6 +++--- examples/count-scalars.roc | 8 ++++---- examples/decode-utf8-stream.roc | 6 +++--- examples/encode-code-points.roc | 7 +++---- examples/estimate-eaw-cells.roc | 8 ++++---- examples/font-script-runs.roc | 8 ++++---- examples/limit-display-name.roc | 6 +++--- examples/line-break-opportunities.roc | 8 ++++---- examples/shaping-facts.roc | 6 +++--- examples/split-graphemes.roc | 8 ++++---- examples/stream-grapheme-ranges.roc | 6 +++--- package/Bidi.roc | 1 - package/InternalCase.roc | 1 - tests/apps/bidi/main.roc | 6 +++--- 16 files changed, 43 insertions(+), 46 deletions(-) diff --git a/.roc-version b/.roc-version index eb9725b..80bf11e 100644 --- a/.roc-version +++ b/.roc-version @@ -1 +1 @@ -nightly-2026-09-16-a49a16f +nightly-2026-10-01-a932c65 diff --git a/examples/CliArgs.roc b/examples/CliArgs.roc index 158d965..e9cdbea 100644 --- a/examples/CliArgs.roc +++ b/examples/CliArgs.roc @@ -21,7 +21,7 @@ CliArgs := [].{ ## Decode argv for an application and report malformed native text as a usage ## error. Applications can then keep their domain logic entirely in Str. - to_strs! : List(OsStr) => Try(List(Str), [Exit(I32), StderrErr(IOErr), ..]) + to_strs! : List(OsStr) => Try(List(Str), [Exit(I32), StderrErr(IOErr)]) to_strs! = |os_args| match decode(os_args) { Ok(args) => Ok(args) diff --git a/examples/bidi-analysis.roc b/examples/bidi-analysis.roc index 6e89bae..0058e46 100644 --- a/examples/bidi-analysis.roc +++ b/examples/bidi-analysis.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -67,11 +67,11 @@ render = |base, analysis, line| { \\mirrored-glyphs: ${format_mirrors(Bidi.line_mirroring(line))} } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? match args { - [_app, base_text, source] => { + [base_text, source] => { base = match parse_base(base_text) { Ok(value) => value Err(UnknownBase(name)) => { diff --git a/examples/count-scalars.roc b/examples/count-scalars.roc index 4572078..ff4b683 100644 --- a/examples/count-scalars.roc +++ b/examples/count-scalars.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -57,12 +57,12 @@ expect scalar_summary("aé🦘").positions == [ "2: value=129432 bytes=3..7", ] -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? text = match args { - [_app] => default_text - [_app, provided] => provided + [] => default_text + [provided] => provided _ => { Stderr.line!("usage: count-scalars [TEXT]")? return Err(Exit(2)) diff --git a/examples/decode-utf8-stream.roc b/examples/decode-utf8-stream.roc index d035388..72f701c 100644 --- a/examples/decode-utf8-stream.roc +++ b/examples/decode-utf8-stream.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -163,10 +163,10 @@ expect { } } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? - chunks = args.drop_first(1) + chunks = args if chunks.is_empty() { Stderr.line!("usage: decode-utf8-stream HEX_BYTES [HEX_BYTES ...]")? Stderr.line!(" bytes are comma-separated; use - for an empty chunk")? diff --git a/examples/encode-code-points.roc b/examples/encode-code-points.roc index c6f65f7..bf0855a 100644 --- a/examples/encode-code-points.roc +++ b/examples/encode-code-points.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -62,11 +62,10 @@ expect encode(["D800"], 4) == Err(Surrogate("D800")) expect encode(["110000"], 4) == Err(OutOfRange("110000")) expect encode(["1F998"], 3) == Err(LimitExceeded({ limit: 3, required: 4 })) -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? - user_args = args.drop_first(1) - (limit_text, tokens) = match user_args { + (limit_text, tokens) = match args { [limit_arg, first, .. as rest] => (limit_arg, [first].concat(rest)) _ => { Stderr.line!("usage: encode-code-points MAX_OUTPUT_BYTES HEX_CODE_POINT [HEX_CODE_POINT ...]")? diff --git a/examples/estimate-eaw-cells.roc b/examples/estimate-eaw-cells.roc index db35bea..ee7e8f7 100644 --- a/examples/estimate-eaw-cells.roc +++ b/examples/estimate-eaw-cells.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", # Use a release bundle URL in applications. The end-to-end suite rewrites # this local development dependency to the bundle served by the test driver. unicode: "../package/main.roc", @@ -48,12 +48,12 @@ expect measure_cells("δΈ–η•Œ") == { cells: 4, scalars: 2 } expect measure_cells("οΌ‘A") == { cells: 3, scalars: 2 } expect measure_cells("é") == { cells: 2, scalars: 2 } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? text = match args { - [_app] => default_text - [_app, provided] => provided + [] => default_text + [provided] => provided _ => { Stderr.line!("usage: estimate-eaw-cells [TEXT]")? return Err(Exit(2)) diff --git a/examples/font-script-runs.roc b/examples/font-script-runs.roc index 30d01f7..7becdc9 100644 --- a/examples/font-script-runs.roc +++ b/examples/font-script-runs.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -114,12 +114,12 @@ expect { } } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? request = match args { - [_app, "complete", preferences, source] => Complete({ preferences, source }) - [_app, "chunks", max_pending, preferences, first, .. as rest] => { + ["complete", preferences, source] => Complete({ preferences, source }) + ["chunks", max_pending, preferences, first, .. as rest] => { Chunks({ max_pending, preferences, chunks: [first].concat(rest) }) } _ => { diff --git a/examples/limit-display-name.roc b/examples/limit-display-name.roc index bbbc794..e6353b0 100644 --- a/examples/limit-display-name.roc +++ b/examples/limit-display-name.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -48,11 +48,11 @@ expect limit_display_name("éclair", 1) == Ok({ slice: "é", truncated: Bool.T expect limit_display_name("πŸ‘©πŸ½β€πŸš€ mission", 1) == Ok({ slice: "πŸ‘©πŸ½β€πŸš€", truncated: Bool.True }) expect limit_display_name("πŸ‡¦πŸ‡Ί team", 1) == Ok({ slice: "πŸ‡¦πŸ‡Ί", truncated: Bool.True }) -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? (limit_text, source) = match args { - [_app, limit_arg, display_name] => (limit_arg, display_name) + [limit_arg, display_name] => (limit_arg, display_name) _ => { Stderr.line!("usage: limit-display-name MAX_GRAPHEMES DISPLAY_NAME")? return Err(Exit(2)) diff --git a/examples/line-break-opportunities.roc b/examples/line-break-opportunities.roc index 5357842..6ed4df1 100644 --- a/examples/line-break-opportunities.roc +++ b/examples/line-break-opportunities.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -108,12 +108,12 @@ expect { } } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? request = match args { - [_app, "complete", profile_text, source] => Complete({ profile_text, source }) - [_app, "chunks", profile_text, first, .. as rest] => Chunks({ profile_text, chunks: [first].concat(rest) }) + ["complete", profile_text, source] => Complete({ profile_text, source }) + ["chunks", profile_text, first, .. as rest] => Chunks({ profile_text, chunks: [first].concat(rest) }) _ => { Stderr.line!("usage: line-break-opportunities complete PROFILE TEXT")? Stderr.line!(" line-break-opportunities chunks PROFILE CHUNK [CHUNK ...]")? diff --git a/examples/shaping-facts.roc b/examples/shaping-facts.roc index bfbd07a..13c7282 100644 --- a/examples/shaping-facts.roc +++ b/examples/shaping-facts.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -140,11 +140,11 @@ expect { and Emoji.variation_presentation(letter, vs16) == None } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? source = match args { - [_app, text] => text + [text] => text _ => { Stderr.line!("usage: shaping-facts TEXT")? return Err(Exit(2)) diff --git a/examples/split-graphemes.roc b/examples/split-graphemes.roc index 0507e20..7207617 100644 --- a/examples/split-graphemes.roc +++ b/examples/split-graphemes.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -58,12 +58,12 @@ expect segment("πŸ‡¦πŸ‡ΊπŸ¦˜") == [ ] expect Grapheme.slices("πŸ‘©β€πŸš€") == ["πŸ‘©β€πŸš€"] -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? source = match args { - [_app] => default_text - [_app, provided] => provided + [] => default_text + [provided] => provided _ => { Stderr.line!("usage: split-graphemes [TEXT]")? return Err(Exit(2)) diff --git a/examples/stream-grapheme-ranges.roc b/examples/stream-grapheme-ranges.roc index bb41ba0..b2bcf97 100644 --- a/examples/stream-grapheme-ranges.roc +++ b/examples/stream-grapheme-ranges.roc @@ -1,5 +1,5 @@ app [main!] { - pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.21.0/4rAQg8kUYZ3Vksr4qMQHpaFYNiHSn9GgS7gVxghd1XYV.tar.zst", + pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.23.0/GNN5tt2gKdX4dhawg4915C4YB193woHFdcCkz31fhGxv.tar.zst", unicode: "../package/main.roc", } @@ -88,10 +88,10 @@ expect { } } -main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr), ..]) +main! : List(OsStr) => Try({}, [Exit(I32), StderrErr(IOErr), StdoutErr(IOErr)]) main! = |os_args| { args = CliArgs.to_strs!(os_args)? - chunks = args.drop_first(1) + chunks = args if chunks.is_empty() { Stderr.line!("usage: stream-grapheme-ranges CHUNK [CHUNK ...]")? Stderr.line!(" chunks must be scalar-aligned; use - for an empty chunk")? diff --git a/package/Bidi.roc b/package/Bidi.roc index f837b14..f8eedf1 100644 --- a/package/Bidi.roc +++ b/package/Bidi.roc @@ -288,7 +288,6 @@ range_from_offsets = |byte_start, byte_end, scalar_start, scalar_end| { } is_p1_range = |source, selected| { - ## This deliberately does not call `p1_ranges`: range analysis must not ## allocate one result per preceding paragraph just to validate `selected`. ## A pending CR delays commitment until the next scalar determines whether diff --git a/package/InternalCase.roc b/package/InternalCase.roc index 28a59a8..0724672 100644 --- a/package/InternalCase.roc +++ b/package/InternalCase.roc @@ -528,7 +528,6 @@ mapping_shape = |mapping, input| match mapping { append_mapping = |initial, mapping| { for_mapping(mapping, initial, |bytes, scalar| append_utf8(bytes, scalar)) - } for_mapping = |mapping, initial, emit| match mapping { diff --git a/tests/apps/bidi/main.roc b/tests/apps/bidi/main.roc index 3c187bc..5bd852c 100644 --- a/tests/apps/bidi/main.roc +++ b/tests/apps/bidi/main.roc @@ -125,7 +125,7 @@ verify_metamorphic_invariants = |protocol_input| { } plain = bidi_result(Bidi.analyze_paragraph("אa${empty_input}", Auto, Bidi.default_limits))? - isolated = bidi_result(Bidi.analyze_paragraph("א⁨a⁩a${empty_input}", Auto, Bidi.default_limits))? + isolated = bidi_result(Bidi.analyze_paragraph("א\u(2068)a\u(2069)a${empty_input}", Auto, Bidi.default_limits))? plain_first = Bidi.entries(plain).get(0) ?? return Err("missing plain first scalar") plain_last = Bidi.entries(plain).get(1) ?? return Err("missing plain last scalar") isolated_first = Bidi.entries(isolated).get(0) ?? return Err("missing isolate first scalar") @@ -208,13 +208,13 @@ verify_mapping_inverse = |visual_to_logical, logical_to_visual, line_start| { verify_control_and_bracket_boundaries : Str -> Try({}, Str) verify_control_and_bracket_boundaries = |protocol_input| { empty_input = protocol_input.drop_last_bytes(protocol_input.count_utf8_bytes()) ?? return Err("could not derive empty protocol input") - controls = Str.join_with([repeat_text("‫", 126), "a", repeat_text("‬", 126), empty_input], "") + controls = Str.join_with([repeat_text("\u(202B)", 126), "a", repeat_text("\u(202C)", 126), empty_input], "") control_analysis = bidi_result(Bidi.analyze_paragraph(controls, Auto, Bidi.default_limits))? verify_level_parity(Bidi.levels(control_analysis))? if !contains_level(Bidi.levels(control_analysis), 126) { return Err("deep explicit controls did not reach the permitted I2 level 126") } - missing_pdi = bidi_result(Bidi.analyze_paragraph("⁨א⁨a${empty_input}", Auto, Bidi.default_limits))? + missing_pdi = bidi_result(Bidi.analyze_paragraph("\u(2068)א\u(2068)a${empty_input}", Auto, Bidi.default_limits))? verify_level_parity(Bidi.levels(missing_pdi))? for depth in [62, 63] {