Skip to content

Commit 99d35b7

Browse files
authored
Asynchronize file copies (#882)
1 parent 2514485 commit 99d35b7

File tree

9 files changed

+79
-23
lines changed

9 files changed

+79
-23
lines changed

src/Library/Library.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export function getDemo(name) {
8080

8181
async function openDemo({ application, demo_name, language }) {
8282
const demo = getDemo(demo_name);
83-
const session = createSessionFromDemo(demo);
83+
const session = await createSessionFromDemo(demo);
8484

8585
if (language) {
8686
session.settings.set_int("code-language", language.index);

src/PanelCode.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@ import Gio from "gi://Gio";
22
import GObject from "gi://GObject";
33

44
import { settings as global_settings, makeDropdownFlat } from "./util.js";
5+
import { setupRustProject } from "./langs/rust/rust.js";
56

6-
export default function PanelCode({ builder, previewer, settings }) {
7+
export default function PanelCode({
8+
builder,
9+
previewer,
10+
session: { settings, file },
11+
}) {
712
const panel_code = builder.get_object("panel_code");
813
const button_code = builder.get_object("button_code");
914
const stack_code = builder.get_object("stack_code");
@@ -47,6 +52,10 @@ export default function PanelCode({ builder, previewer, settings }) {
4752
panel.language = dropdown_code_lang.selected_item?.string;
4853
stack_code.visible_child_name = panel.language;
4954
previewer.useInternal().catch(console.error);
55+
56+
if (panel.language.toLowerCase() === "rust") {
57+
setupRustProject(file).catch(console.error);
58+
}
5059
}
5160
switchLanguage();
5261

src/application.js

+3-6
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,11 @@ function setColorScheme() {
7575
setColorScheme();
7676
settings.connect("changed::color-scheme", setColorScheme);
7777

78-
// We are not using async otherwise the app segfaults
79-
// does not like opening a window in a promise
80-
// TODO: make a reproducer and file a GJS bug
8178
function restoreSessions() {
8279
const sessions = getSessions();
8380

8481
if (sessions.length < 1) {
85-
bootstrap();
82+
bootstrap().catch(console.error);
8683
} else {
8784
sessions.forEach((session) => {
8885
const { load } = Window({
@@ -94,15 +91,15 @@ function restoreSessions() {
9491
}
9592
}
9693

97-
function bootstrap() {
94+
async function bootstrap() {
9895
const first_run = settings.get_boolean("first-run");
9996
if (!first_run) {
10097
application.activate_action("library", null);
10198
return;
10299
}
103100

104101
const demo = getDemo("Welcome");
105-
const session = createSessionFromDemo(demo);
102+
const session = await createSessionFromDemo(demo);
106103
const { load, window } = Window({
107104
application,
108105
session,

src/init.js

+2
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,5 @@ Gio._promisify(
9696
"next_files_async",
9797
"next_files_finish",
9898
);
99+
100+
Gio._promisify(Gio.File.prototype, "copy_async", "copy_finish");

src/langs/rust/Compiler.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import Gio from "gi://Gio";
22
import GLib from "gi://GLib";
33
import dbus_previewer from "../../Previewer/DBusPreviewer.js";
4-
import { copyDirectory, decode, encode } from "../../util.js";
5-
import { rust_template_dir } from "./rust.js";
4+
import { decode, encode } from "../../util.js";
5+
import { installRustLibraries } from "./rust.js";
66

77
export default function Compiler({ session }) {
88
const { file } = session;
@@ -16,7 +16,7 @@ export default function Compiler({ session }) {
1616
let savedRustcVersion;
1717

1818
async function compile() {
19-
copyDirectory(rust_template_dir, file);
19+
await installRustLibraries(file);
2020

2121
rustcVersion ||= await getRustcVersion();
2222
savedRustcVersion ||= await getSavedRustcVersion({ rustcVersionFile });

src/langs/rust/rust.js

+39-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import Gio from "gi://Gio";
2+
import GLib from "gi://GLib";
23

34
import { createLSPClient } from "../../common.js";
45
import { getLanguage } from "../../util.js";
@@ -32,6 +33,43 @@ export function setup({ document }) {
3233
return lspc;
3334
}
3435

35-
export const rust_template_dir = Gio.File.new_for_path(
36+
const rust_template_dir = Gio.File.new_for_path(
3637
pkg.pkgdatadir,
3738
).resolve_relative_path("langs/rust/template");
39+
40+
export async function setupRustProject(destination) {
41+
return Promise.all([
42+
copy("Cargo.toml", rust_template_dir, destination, Gio.FileCopyFlags.NONE),
43+
copy("Cargo.lock", rust_template_dir, destination, Gio.FileCopyFlags.NONE),
44+
]);
45+
}
46+
47+
export async function installRustLibraries(destination) {
48+
return Promise.all([
49+
copy("lib.rs", rust_template_dir, destination, Gio.FileCopyFlags.OVERWRITE),
50+
copy(
51+
"workbench.rs",
52+
rust_template_dir,
53+
destination,
54+
Gio.FileCopyFlags.OVERWRITE,
55+
),
56+
]);
57+
}
58+
59+
async function copy(filename, source_dir, dest_dir, flags) {
60+
const file = source_dir.get_child(filename);
61+
try {
62+
await file.copy_async(
63+
dest_dir.get_child(file.get_basename()),
64+
flags,
65+
GLib.PRIORITY_DEFAULT,
66+
null,
67+
null,
68+
null,
69+
);
70+
} catch (err) {
71+
if (!err.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.EXISTS)) {
72+
throw err;
73+
}
74+
}
75+
}

src/sessions.js

+11-5
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
copyDirectory,
1414
} from "./util.js";
1515
import { languages } from "./common.js";
16-
import { rust_template_dir } from "./langs/rust/rust.js";
1716

1817
export const sessions_dir = data_dir.get_child("sessions");
1918

@@ -57,16 +56,16 @@ function createSession() {
5756
return session;
5857
}
5958

60-
export function createSessionFromDemo(demo) {
59+
export async function createSessionFromDemo(demo) {
6160
const { name, panels } = demo;
6261

6362
const session = createSession();
6463
const demo_dir = demos_dir.get_child(name);
6564

6665
const { file, settings } = session;
67-
copyDirectory(demo_dir, file);
68-
copyDirectory(rust_template_dir, file);
66+
await copyDirectory(demo_dir, file);
6967

68+
settings.delay();
7069
settings.set_string("name", name);
7170
settings.set_boolean("show-code", panels.includes("code"));
7271
settings.set_boolean("show-style", panels.includes("style"));
@@ -76,6 +75,7 @@ export function createSessionFromDemo(demo) {
7675
"code-language",
7776
global_settings.get_int("recent-code-language"),
7877
);
78+
settings.apply();
7979

8080
return session;
8181
}
@@ -84,7 +84,13 @@ export async function deleteSession(session) {
8484
// There is no method to recursively delete a folder so we trash instead
8585
// https://github.com/flatpak/xdg-desktop-portal/issues/630 :/
8686
// portal.trash_file(file.get_path(), null).catch(console.error);
87-
session.file.trash(null);
87+
try {
88+
session.file.trash(null);
89+
} catch (err) {
90+
if (!err.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.EXISTS)) {
91+
throw err;
92+
}
93+
}
8894
}
8995

9096
export async function saveSessionAsProject(session, destination) {

src/util.js

+9-5
Original file line numberDiff line numberDiff line change
@@ -104,19 +104,23 @@ export const demos_dir = Gio.File.new_for_path(
104104
).resolve_relative_path("demos");
105105

106106
// There is no copy directory function
107-
export function copyDirectory(source, destination) {
108-
for (const file_info of source.enumerate_children(
109-
"",
107+
export async function copyDirectory(source, destination) {
108+
const enumerator = await source.enumerate_children_async(
109+
"standard::name",
110110
Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
111+
GLib.PRIORITY_DEFAULT,
111112
null,
112-
)) {
113+
);
114+
115+
for await (const file_info of enumerator) {
113116
if (file_info.get_file_type() === Gio.FileType.DIRECTORY) continue;
114117
const child = source.get_child(file_info.get_name());
115118

116119
try {
117-
child.copy(
120+
await child.copy_async(
118121
destination.get_child(child.get_basename()),
119122
Gio.FileCopyFlags.NONE,
123+
GLib.PRIORITY_DEFAULT,
120124
null,
121125
null,
122126
);

src/window.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export default function Window({ application, session }) {
154154
const panel_code = PanelCode({
155155
builder,
156156
previewer,
157-
settings,
157+
session,
158158
});
159159

160160
previewer.setPanelCode(panel_code);

0 commit comments

Comments
 (0)