From fb7468c3f576d921a7ffcd45aeb0675d074bc122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Mon, 9 Nov 2026 16:23:47 +0100 Subject: [PATCH] :wrench: Make all CI jobs use Rust 1.99 (#12903) * :wrench: Bump Rust version of the devenv image to 1.99 * :wrench: Run the pinned Rust setup from the lint and format scripts ./build and ./test switch to the Rust version in render-wasm/_build_env through setup, but ./lint did not, and formatting called cargo fmt directly. In CI both ran on the devenv image's default toolchain. Make ./lint run setup and add a ./fmt script that does the same, so all render-wasm entry points use the pinned version. CI and scripts/ci now call ./fmt instead of cargo fmt. AI-assisted-by: claude-opus-5-5 --- .github/workflows/tests-wasm.yml | 2 +- .serena/memories/render-wasm/core.md | 3 ++- .serena/memories/scripts/ci.md | 2 +- docker/devenv/Dockerfile | 2 +- render-wasm/README.md | 5 +++-- render-wasm/fmt | 18 ++++++++++++++++++ render-wasm/lint | 2 ++ render-wasm/src/math/bools.rs | 6 +----- render-wasm/src/tiles.rs | 3 ++- render-wasm/src/wasm/fills.rs | 10 ++++------ render-wasm/src/wasm/text/helpers.rs | 28 +++++++++------------------- render-wasm/src/wasm/ui.rs | 6 ++++-- scripts/ci | 4 ++-- 13 files changed, 50 insertions(+), 41 deletions(-) create mode 100755 render-wasm/fmt diff --git a/.github/workflows/tests-wasm.yml b/.github/workflows/tests-wasm.yml index f3e1547321..2047126ed0 100644 --- a/.github/workflows/tests-wasm.yml +++ b/.github/workflows/tests-wasm.yml @@ -49,7 +49,7 @@ jobs: - name: Format working-directory: ./render-wasm run: | - cargo fmt --check + ./fmt --check - name: Lint working-directory: ./render-wasm diff --git a/.serena/memories/render-wasm/core.md b/.serena/memories/render-wasm/core.md index c3b8dd1db7..4777620d11 100644 --- a/.serena/memories/render-wasm/core.md +++ b/.serena/memories/render-wasm/core.md @@ -36,6 +36,7 @@ From `render-wasm/`: - Rust tests: `./test` or `cargo test `. - Cross-cutting testing principles and anti-patterns: `mem:testing`. - Lint: `./lint`. -- Format check: `cargo fmt --check`. +- Format: `./fmt`; check only: `./fmt --check`. +- `./build`, `./test`, `./lint` and `./fmt` all run `setup`, which selects the Rust version pinned in `_build_env` (skip with `PENPOT_WASM_PREPARED=1`). Do not change exported WASM function signatures without updating the corresponding frontend bridge and verifying the frontend renderer path. \ No newline at end of file diff --git a/.serena/memories/scripts/ci.md b/.serena/memories/scripts/ci.md index be509b7a22..99167efded 100644 --- a/.serena/memories/scripts/ci.md +++ b/.serena/memories/scripts/ci.md @@ -106,7 +106,7 @@ produce deployable artifacts. ## Notes - `mcp` has no lint task and `media-processor` has no lint task; both show - as skipped. `render-wasm` uses `./lint`, `./test`, and `cargo fmt`. + as skipped. `render-wasm` uses `./lint`, `./test`, and `./fmt`. - `scripts/test_ci.py` (unittest, `python3 scripts/test_ci.py`) covers the flag wiring, one build command per module and the help text through `--dry-run`; it executes no real build. diff --git a/docker/devenv/Dockerfile b/docker/devenv/Dockerfile index 2ad410058f..5a521d786f 100644 --- a/docker/devenv/Dockerfile +++ b/docker/devenv/Dockerfile @@ -187,7 +187,7 @@ ENV PATH=/opt/cargo/bin:$PATH \ RUSTUP_HOME=/opt/rustup \ CARGO_HOME=/opt/cargo \ RUSTUP_VERSION=1.28.2 \ - RUST_VERSION=1.91.0 \ + RUST_VERSION=1.99.0 \ EMSCRIPTEN_VERSION=4.0.6 WORKDIR /opt diff --git a/render-wasm/README.md b/render-wasm/README.md index 736b540bc2..48a6a3cb81 100644 --- a/render-wasm/README.md +++ b/render-wasm/README.md @@ -54,8 +54,9 @@ between them does not invalidate the other's cache. Set `BUILD_MODE=release` Set `PENPOT_WASM_PREPARED=1` when the pinned Rust toolchain is selected, its Emscripten target is installed, and this package's Node dependencies are -installed. `./build` and `./test` then skip `rustup` setup and `pnpm install`. -Benchmark preparation sets this flag for each retained build. +installed. `./build`, `./test`, `./lint` and `./fmt` then skip `rustup` setup +and `pnpm install`. Benchmark preparation sets this flag for each retained +build. ### Serialize builds in one checkout diff --git a/render-wasm/fmt b/render-wasm/fmt new file mode 100755 index 0000000000..b7a9b8118f --- /dev/null +++ b/render-wasm/fmt @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +# Usage: ./fmt [--check] [extra cargo fmt params...] +# +# Formats the crate with the Rust toolchain pinned in `_build_env`. Set +# PENPOT_WASM_PREPARED=1 to skip the toolchain setup. + +set -e + +_SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) +pushd "$_SCRIPT_DIR" > /dev/null + +. ./_build_env frontend + +setup +cargo fmt "$@" + +popd > /dev/null diff --git a/render-wasm/lint b/render-wasm/lint index 097a4314cf..ca605e8ec9 100755 --- a/render-wasm/lint +++ b/render-wasm/lint @@ -10,6 +10,8 @@ fi . ./_build_env frontend +setup || exit $? + ALLOWED_RULES="-D static_mut_refs" # ./lint --fix diff --git a/render-wasm/src/math/bools.rs b/render-wasm/src/math/bools.rs index cb300d83d9..653ab6cc8f 100644 --- a/render-wasm/src/math/bools.rs +++ b/render-wasm/src/math/bools.rs @@ -419,11 +419,7 @@ fn beziers_to_segments(beziers: &[(BezierSource, Bezier)]) -> Vec { let mut last_end = (first_bezier.end.x as f32, first_bezier.end.y as f32); let mut cur_end = first_bezier.end; - loop { - let Some((next_src, next_bezier)) = find_next_in_pool(&mut pool, cur_end, cur_src) - else { - break; - }; + while let Some((next_src, next_bezier)) = find_next_in_pool(&mut pool, cur_end, cur_src) { push_bezier(&mut result, &next_bezier); last_end = (next_bezier.end.x as f32, next_bezier.end.y as f32); cur_end = next_bezier.end; diff --git a/render-wasm/src/tiles.rs b/render-wasm/src/tiles.rs index 8180266fb9..2dbfec39b4 100644 --- a/render-wasm/src/tiles.rs +++ b/render-wasm/src/tiles.rs @@ -444,7 +444,8 @@ impl PendingTiles { // Farthest first, since we use pop() to process the tiles // in order of priority (closest first) - self.tile_order.sort_unstable_by(|a, b| b.0.cmp(&a.0)); + self.tile_order + .sort_unstable_by_key(|a| std::cmp::Reverse(a.0)); for (_, tile) in self.tile_order.iter() { let tile = *tile; diff --git a/render-wasm/src/wasm/fills.rs b/render-wasm/src/wasm/fills.rs index 28ff005bec..3de2b4dd79 100644 --- a/render-wasm/src/wasm/fills.rs +++ b/render-wasm/src/wasm/fills.rs @@ -87,13 +87,11 @@ impl TryFrom<&[u8]> for RawFillData { // FIXME: return Result pub fn read_fills_from_bytes(buffer: &[u8], num_fills: usize) -> Vec { buffer - .chunks_exact(RAW_FILL_DATA_SIZE) + .as_chunks::() + .0 + .iter() .take(num_fills) - .map(|bytes| { - RawFillData::try_from(bytes) - .expect("Invalid fill data") - .into() - }) + .map(|bytes| RawFillData::from(*bytes).into()) .collect() } diff --git a/render-wasm/src/wasm/text/helpers.rs b/render-wasm/src/wasm/text/helpers.rs index f9ccfebdd0..be51aadcb2 100644 --- a/render-wasm/src/wasm/text/helpers.rs +++ b/render-wasm/src/wasm/text/helpers.rs @@ -297,12 +297,9 @@ pub fn replace_text_with_newlines( let mut current_cursor = *cursor; - if let Some(new_offset) = replace_text_at_cursor(text_content, ¤t_cursor, lines[0]) { - current_cursor = - TextPositionWithAffinity::new_downstream_affinity(current_cursor.paragraph, new_offset); - } else { - return None; - } + let new_offset = replace_text_at_cursor(text_content, ¤t_cursor, lines[0])?; + current_cursor = + TextPositionWithAffinity::new_downstream_affinity(current_cursor.paragraph, new_offset); for line in lines.iter().skip(1) { if !split_paragraph_at_cursor(text_content, ¤t_cursor) { @@ -336,12 +333,9 @@ pub fn insert_text_with_newlines( let mut current_cursor = *cursor; - if let Some(new_offset) = insert_text_at_cursor(text_content, ¤t_cursor, lines[0]) { - current_cursor = - TextPositionWithAffinity::new_downstream_affinity(current_cursor.paragraph, new_offset); - } else { - return None; - } + let new_offset = insert_text_at_cursor(text_content, ¤t_cursor, lines[0])?; + current_cursor = + TextPositionWithAffinity::new_downstream_affinity(current_cursor.paragraph, new_offset); for line in lines.iter().skip(1) { if !split_paragraph_at_cursor(text_content, ¤t_cursor) { @@ -477,8 +471,7 @@ pub fn delete_selection_range(text_content: &mut TextContent, selection: &TextSe delete_range_in_paragraph(&mut paragraphs[end_paragraph], 0, end.offset); - let end_para_children: Vec<_> = - paragraphs[end_paragraph].children_mut().drain(..).collect(); + let end_para_children: Vec<_> = std::mem::take(paragraphs[end_paragraph].children_mut()); paragraphs[start.paragraph] .children_mut() .extend(end_para_children); @@ -593,10 +586,7 @@ pub fn delete_char_before( let paragraphs = text_content.paragraphs_mut(); let prev_para_len = paragraph_char_count(¶graphs[prev_para_idx]); - let current_children: Vec<_> = paragraphs[cursor.paragraph] - .children_mut() - .drain(..) - .collect(); + let current_children: Vec<_> = std::mem::take(paragraphs[cursor.paragraph].children_mut()); paragraphs[prev_para_idx] .children_mut() .extend(current_children); @@ -770,7 +760,7 @@ pub fn delete_char_after(text_content: &mut TextContent, cursor: &TextPositionWi delete_range_in_paragraph(para, cursor.offset, end); } else if cursor.paragraph < paragraphs.len() - 1 { let next_para_idx = cursor.paragraph + 1; - let next_children: Vec<_> = paragraphs[next_para_idx].children_mut().drain(..).collect(); + let next_children: Vec<_> = std::mem::take(paragraphs[next_para_idx].children_mut()); paragraphs[cursor.paragraph] .children_mut() .extend(next_children); diff --git a/render-wasm/src/wasm/ui.rs b/render-wasm/src/wasm/ui.rs index 3ef343618c..f63bccfd2d 100644 --- a/render-wasm/src/wasm/ui.rs +++ b/render-wasm/src/wasm/ui.rs @@ -76,11 +76,13 @@ impl TryFrom<&[u8]> for RawGuide { fn read_guides_from_bytes(buffer: &[u8], count: usize) -> Result> { buffer - .chunks_exact(RAW_GUIDE_SIZE) + .as_chunks::() + .0 + .iter() .take(count) .enumerate() .map(|(i, bytes)| { - RawGuide::try_from(bytes).map(|raw_guide| { + RawGuide::try_from(bytes.as_slice()).map(|raw_guide| { let mut guide: Guide = raw_guide.into(); guide.index = i; guide diff --git a/scripts/ci b/scripts/ci index db58292ae9..e2ed5cd6e0 100755 --- a/scripts/ci +++ b/scripts/ci @@ -55,7 +55,7 @@ declare -A FMT_CHECK_CMD=( [frontend]="pnpm run check-fmt:clj && pnpm run check-fmt:js && pnpm run check-fmt:scss" [backend]="pnpm run check-fmt:clj" [common]="pnpm run check-fmt:clj && pnpm run check-fmt:js" - [render-wasm]="cargo fmt --check" + [render-wasm]="./fmt --check" [exporter]="pnpm run check-fmt:clj" [mcp]="pnpm run fmt:check" [plugins]="pnpm run format:check" @@ -67,7 +67,7 @@ declare -A FMT_FIX_CMD=( [frontend]="pnpm run fmt:clj && pnpm run fmt:js && pnpm run fmt:scss" [backend]="pnpm run fmt:clj" [common]="pnpm run fmt:clj && pnpm run fmt:js" - [render-wasm]="cargo fmt" + [render-wasm]="./fmt" [exporter]="pnpm run fmt:clj" [mcp]="pnpm run fmt" [plugins]="pnpm run format"