From 59a693e31e1611dbcf3227550243f4a0acbd74fb Mon Sep 17 00:00:00 2001
From: Jamie Benstead <57325966+jamiebenstead@users.noreply.github.com>
Date: Fri, 21 Feb 2025 16:09:06 +0000
Subject: [PATCH 1/6] Update version (#1197)
## What's Changed
* Check instructions length before setting option value by
@jamiebenstead in
https://github.com/RaspberryPiFoundation/editor-ui/pull/1196
**Full Changelog**:
https://github.com/RaspberryPiFoundation/editor-ui/compare/v0.29.0...v0.29.1
---
CHANGELOG.md | 5 +++--
package.json | 2 +-
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e10c5248a..fc5a14d0f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
-## Unreleased
+## [0.29.1] - 2025-02-21
### Fixed
@@ -1066,7 +1066,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Events in Web Component indicating whether Mission Zero criteria have been met (#113)
-[unreleased]: https://github.com/RaspberryPiFoundation/editor-ui/compare/v0.29.0...HEAD
+[unreleased]: https://github.com/RaspberryPiFoundation/editor-ui/compare/v0.29.1...HEAD
+[0.29.1]: https://github.com/RaspberryPiFoundation/editor-ui/releases/tag/v0.29.1
[0.29.0]: https://github.com/RaspberryPiFoundation/editor-ui/releases/tag/v0.29.0
[0.28.14]: https://github.com/RaspberryPiFoundation/editor-ui/releases/tag/v0.28.14
[0.28.13]: https://github.com/RaspberryPiFoundation/editor-ui/releases/tag/v0.28.13
diff --git a/package.json b/package.json
index af4712906..ac2528a4e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@raspberrypifoundation/editor-ui",
- "version": "0.29.0",
+ "version": "0.29.1",
"private": true,
"dependencies": {
"@apollo/client": "^3.7.8",
From 32315918c557b025f4d5dbc6148906812dcda3ab Mon Sep 17 00:00:00 2001
From: Lois Wells <88904316+loiswells97@users.noreply.github.com>
Date: Mon, 24 Mar 2025 15:58:09 +0000
Subject: [PATCH 2/6] Fixing the append file write mode (#1200)
## What's Changed?
- Fixed the mode on the `pyodide` side - it was always using `w` rather
than the mode provided in the code
- Fixed the file write append mode on the frontend - it was incorrectly
adding a newline character before anything was appended.
---
CHANGELOG.md | 6 ++++++
src/PyodideWorker.js | 2 +-
.../Runners/PythonRunner/PyodideRunner/PyodideRunner.jsx | 2 +-
.../PythonRunner/PyodideRunner/PyodideRunner.test.js | 4 ++--
4 files changed, 10 insertions(+), 4 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fc5a14d0f..0e42619de 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## Unreleased
+
+### Fixed
+
+- Bugs in append mode for writing to files in python (#1200)
+
## [0.29.1] - 2025-02-21
### Fixed
diff --git a/src/PyodideWorker.js b/src/PyodideWorker.js
index 200c742b0..811467bb3 100644
--- a/src/PyodideWorker.js
+++ b/src/PyodideWorker.js
@@ -116,7 +116,7 @@ const PyodideWorker = () => {
self.content += content
if len(self.content) > MAX_FILE_SIZE:
raise OSError(f"File '{self.filename}' exceeds maximum file size of {MAX_FILE_SIZE} bytes")
- with _original_open(self.filename, "w") as f:
+ with _original_open(self.filename, mode) as f:
f.write(self.content)
basthon.kernel.write_file({ "filename": self.filename, "content": self.content, "mode": mode })
diff --git a/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.jsx b/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.jsx
index 50594e250..0d39afe80 100644
--- a/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.jsx
+++ b/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.jsx
@@ -223,7 +223,7 @@ const PyodideRunner = ({ active, outputPanels = ["text", "visual"] }) => {
updatedContent = content;
} else if (mode === "a") {
updatedContent =
- (componentToUpdate ? componentToUpdate.content + "\n" : "") + content;
+ (componentToUpdate ? componentToUpdate.content : "") + content;
}
if (componentToUpdate) {
diff --git a/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.test.js b/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.test.js
index bea6c9264..fef816ebe 100644
--- a/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.test.js
+++ b/src/components/Editor/Runners/PythonRunner/PyodideRunner/PyodideRunner.test.js
@@ -307,7 +307,7 @@ describe("When file write event is received", () => {
worker.postMessageFromWorker({
method: "handleFileWrite",
filename: "existing_file.txt",
- content: "new content",
+ content: "\nnew content",
mode: "a",
});
expect(dispatchSpy).toHaveBeenCalledWith({
@@ -364,7 +364,7 @@ describe("When file write event is received", () => {
worker.postMessageFromWorker({
method: "handleFileWrite",
filename: "existing_file.txt",
- content: "new content",
+ content: "\nnew content",
mode: "a",
});
expect(dispatchSpy).toHaveBeenCalledWith({
From 8df5e6d26757f6ae7d1ef7524b5fef46d1821636 Mon Sep 17 00:00:00 2001
From: Lois Wells <88904316+loiswells97@users.noreply.github.com>
Date: Thu, 3 Apr 2025 14:21:51 +0100
Subject: [PATCH 3/6] Added project load failed custom event (#1201)
---
CHANGELOG.md | 4 ++
src/containers/WebComponentLoader.jsx | 11 ++++-
src/containers/WebComponentLoader.test.js | 60 ++++++++++++++++++++++-
src/events/WebComponentCustomEvents.js | 4 ++
4 files changed, 77 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0e42619de..d0c21414b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
## Unreleased
+### Added
+
+- `editor-projectLoadFailed` custom event that fires when a project completely fails to load (#1201)
+
### Fixed
- Bugs in append mode for writing to files in python (#1200)
diff --git a/src/containers/WebComponentLoader.jsx b/src/containers/WebComponentLoader.jsx
index d6cae9700..adaee80ba 100644
--- a/src/containers/WebComponentLoader.jsx
+++ b/src/containers/WebComponentLoader.jsx
@@ -26,7 +26,10 @@ import externalStyles from "../assets/stylesheets/ExternalStyles.scss";
import editorStyles from "../assets/stylesheets/index.scss";
import "../assets/stylesheets/Notifications.scss";
import Style from "style-it";
-import { projectOwnerLoadedEvent } from "../events/WebComponentCustomEvents";
+import {
+ projectLoadFailed,
+ projectOwnerLoadedEvent,
+} from "../events/WebComponentCustomEvents";
const WebComponentLoader = (props) => {
const {
@@ -112,6 +115,12 @@ const WebComponentLoader = (props) => {
}
}, [loading, project]);
+ useEffect(() => {
+ if (loading === "failed" && !remixLoadFailed) {
+ document.dispatchEvent(projectLoadFailed);
+ }
+ }, [loading, remixLoadFailed]);
+
useEffect(() => {
if (justLoaded) {
document.dispatchEvent(projectOwnerLoadedEvent(projectOwner));
diff --git a/src/containers/WebComponentLoader.test.js b/src/containers/WebComponentLoader.test.js
index c8a7df9d0..ed42a94c0 100644
--- a/src/containers/WebComponentLoader.test.js
+++ b/src/containers/WebComponentLoader.test.js
@@ -535,7 +535,7 @@ describe("When user is in state", () => {
const mockStore = configureStore(middlewares);
const initialState = {
editor: {
- loading: "idle",
+ loading: "failed",
project: {
components: [],
},
@@ -581,6 +581,16 @@ describe("When user is in state", () => {
reactAppApiEndpoint: "http://localhost:3009/",
});
});
+
+ test("Does not trigger project load failed event", () => {
+ expect(document.dispatchEvent).not.toHaveBeenCalledWith(
+ new CustomEvent("editor-projectLoadFailed", {
+ bubbles: true,
+ cancelable: false,
+ composed: true,
+ }),
+ );
+ });
});
afterEach(async () => {
@@ -588,4 +598,52 @@ describe("When user is in state", () => {
await act(async () => cookies.remove("theme"));
});
});
+
+ describe("when a project fails to load", () => {
+ beforeEach(() => {
+ localStorage.setItem(authKey, JSON.stringify(user));
+ const middlewares = [];
+ const mockStore = configureStore(middlewares);
+ const initialState = {
+ editor: {
+ loading: "failed",
+ project: {
+ components: [],
+ },
+ openFiles: [],
+ focussedFileIndices: [],
+ hasShownSavePrompt: false,
+ remixLoadFailed: false,
+ justLoaded: false,
+ saveTriggered: false,
+ },
+ instructions: {},
+ auth: { user },
+ };
+ store = mockStore(initialState);
+ cookies = new Cookies();
+ render(
+
{ { name: "main", extension: "py", - content: "import py5_imported", + content: "# input.comment.py5", }, ], image_list: [], @@ -563,7 +563,7 @@ describe("When in split view, sense_hat imported and code run", () => { { name: "main", extension: "py", - content: "import _internal_sense_hat", + content: "import sense_hat", }, ], image_list: [], @@ -675,7 +675,7 @@ describe("When in tabbed view, py5 imported and code run", () => { )); }); - test("Output view toggle not shown", () => { + test("Output view toggle is shown", () => { expect( screen.queryByText("outputViewToggle.buttonSplitLabel"), ).toBeInTheDocument(); @@ -704,7 +704,7 @@ describe("When in tabbed view, py5_imported imported and code run", () => { { name: "main", extension: "py", - content: "import py5_imported", + content: "# input.comment.py5", }, ], image_list: [], @@ -724,7 +724,7 @@ describe("When in tabbed view, py5_imported imported and code run", () => { )); }); - test("Output view toggle not shown", () => { + test("Output view toggle is shown", () => { expect( screen.queryByText("outputViewToggle.buttonSplitLabel"), ).toBeInTheDocument(); @@ -769,7 +769,7 @@ describe("When in tabbed view, pygal imported and code run", () => { )); }); - test("Output view toggle not shown", () => { + test("Output view toggle is shown", () => { expect( screen.queryByText("outputViewToggle.buttonSplitLabel"), ).toBeInTheDocument(); @@ -814,7 +814,8 @@ describe("When in tabbed view, turtle imported and code run", () => { )); }); - test("Output view toggle not shown", () => { + test("Output view toggle is shown", () => { + screen.debug(); expect( screen.queryByText("outputViewToggle.buttonSplitLabel"), ).toBeInTheDocument(); @@ -839,7 +840,7 @@ describe("When in tabbed view, sense_hat imported and code run", () => { { name: "main", extension: "py", - content: "import _internal_sense_hat", + content: "import sense_hat", }, ], image_list: [], @@ -859,7 +860,7 @@ describe("When in tabbed view, sense_hat imported and code run", () => { )); }); - test("Output view toggle not shown", () => { + test("Output view toggle is shown", () => { expect( screen.queryByText("outputViewToggle.buttonSplitLabel"), ).toBeInTheDocument(); diff --git a/src/utils/getPythonImports.js b/src/utils/getPythonImports.js new file mode 100644 index 000000000..e06c4f383 --- /dev/null +++ b/src/utils/getPythonImports.js @@ -0,0 +1,22 @@ +export const getPythonImports = (code, t) => { + const codeWithoutMultilineStrings = code.replace( + /'''[\s\S]*?'''|"""[\s\S]*?"""/gm, + "", + ); + const importRegex = + /(?<=^\s*)(from\s+([a-zA-Z0-9_.]+)(\s+import\s+([a-zA-Z0-9_.]+))?)|(?<=^\s*)(import\s+([a-zA-Z0-9_.]+))/gm; + const matches = codeWithoutMultilineStrings.match(importRegex); + const imports = matches + ? matches.map( + (match) => + match + .split(/from|import/) + .filter(Boolean) + .map((s) => s.trim())[0], + ) + : []; + if (code.includes(`# ${t("input.comment.py5")}`)) { + imports.push("py5_imported"); + } + return imports; +}; From 29b3b3faca403443acc16b5b5888fd2c646ae02f Mon Sep 17 00:00:00 2001 From: Lois Wells <88904316+loiswells97@users.noreply.github.com> Date: Tue, 15 Apr 2025 11:19:32 +0100 Subject: [PATCH 6/6] v0.30.0 (#1207) ### Added - `editor-projectLoadFailed` custom event that fires when a project completely fails to load (#1201) - Added runnerBeingLoaded state to prevent race condition overwrites (#1205) ### Fixed - Bugs in append mode for writing to files in python (#1200) - `turtle` bug that did not display output on first code run (#1203) --- CHANGELOG.md | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1b6d33e3..b3d7fb495 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## Unreleased +## [0.30.0] - 2025-04-15 + ### Added - `editor-projectLoadFailed` custom event that fires when a project completely fails to load (#1201) @@ -1079,6 +1081,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - Events in Web Component indicating whether Mission Zero criteria have been met (#113) [unreleased]: https://github.com/RaspberryPiFoundation/editor-ui/compare/v0.29.1...HEAD +[0.30.0]: https://github.com/RaspberryPiFoundation/editor-ui/releases/tag/v0.30.0 [0.29.1]: https://github.com/RaspberryPiFoundation/editor-ui/releases/tag/v0.29.1 [0.29.0]: https://github.com/RaspberryPiFoundation/editor-ui/releases/tag/v0.29.0 [0.28.14]: https://github.com/RaspberryPiFoundation/editor-ui/releases/tag/v0.28.14 diff --git a/package.json b/package.json index ac2528a4e..63d3a2617 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@raspberrypifoundation/editor-ui", - "version": "0.29.1", + "version": "0.30.0", "private": true, "dependencies": { "@apollo/client": "^3.7.8",