Skip to content

Commit efbb3da

Browse files
committed
Fix: package server as a VSCode extension.
1 parent 0514821 commit efbb3da

File tree

16 files changed

+415
-185
lines changed

16 files changed

+415
-185
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ Changelog
2222
[Github master](https://github.com/bjones1/CodeChat_Editor)
2323
-----------------------------------------------------------
2424

25-
* No changes.
25+
* Embed the CodeChat Editor Server inside the VSCode extension, rather than
26+
running it as a standalone binary.
2627

2728
Version 0.1.34 -- 2025-Sep-08
2829
-----------------------------

builder/src/main.rs

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,11 @@ fn quick_copy_dir<P: AsRef<Path>>(src: P, dest: P, files: Option<P>) -> io::Resu
242242
}
243243
}
244244

245+
fn copy_file<P: AsRef<Path> + std::fmt::Debug>(src: P, dest: P) -> io::Result<()> {
246+
println!("copy {src:?} -> {dest:?}");
247+
fs::copy(src, dest).map(|_| ())
248+
}
249+
245250
fn remove_dir_all_if_exists<P: AsRef<Path> + std::fmt::Display>(path: P) -> io::Result<()> {
246251
if Path::new(path.as_ref()).try_exists().unwrap() {
247252
fs::remove_dir_all(path.as_ref())?;
@@ -357,6 +362,8 @@ fn run_install(dev: bool) -> io::Result<()> {
357362
run_cmd!(
358363
info "Builder: cargo fetch";
359364
cargo fetch --manifest-path=../builder/Cargo.toml;
365+
info "VSCode extension: cargo fetch";
366+
cargo fetch --manifest-path=../extensions/VSCode/Cargo.toml;
360367
info "cargo fetch";
361368
cargo fetch;
362369
)?;
@@ -387,6 +394,8 @@ fn run_update() -> io::Result<()> {
387394
run_cmd!(
388395
info "Builder: cargo update";
389396
cargo update --manifest-path=../builder/Cargo.toml;
397+
info "VSCoe extension: cargo update";
398+
cargo update --manifest-path=../extensions/VSCode/Cargo.toml;
390399
info "cargo update";
391400
cargo update;
392401
)?;
@@ -396,6 +405,8 @@ fn run_update() -> io::Result<()> {
396405
run_cmd!(
397406
info "Builder: cargo outdated";
398407
cargo outdated --manifest-path=../builder/Cargo.toml;
408+
info "VSCode extension: cargo outdated";
409+
cargo outdated --manifest-path=../extensions/VSCode/Cargo.toml;
399410
info "cargo outdated";
400411
cargo outdated;
401412
)?;
@@ -412,11 +423,17 @@ fn run_test() -> io::Result<()> {
412423
info "Builder: cargo clippy and fmt";
413424
cargo clippy --all-targets --manifest-path=../builder/Cargo.toml -- -D warnings;
414425
cargo fmt --check --manifest-path=../builder/Cargo.toml;
426+
info "VSCode extension: cargo clippy and fmt";
427+
cargo clippy --all-targets --manifest-path=../extensions/VSCode/Cargo.toml -- -D warnings;
428+
cargo fmt --check --manifest-path=../extensions/VSCode/Cargo.toml;
415429
info "cargo sort";
416430
cargo sort --check;
417431
cd ../builder;
418432
info "Builder: cargo sort";
419433
cargo sort --check;
434+
cd ../extensions/VSCode;
435+
info "VSCode extension: cargo sort";
436+
cargo sort --check;
420437
)?;
421438
run_build()?;
422439
// Verify that compiling for release produces no errors.
@@ -428,6 +445,8 @@ fn run_test() -> io::Result<()> {
428445
run_cmd!(
429446
info "Builder: cargo test";
430447
cargo test --manifest-path=../builder/Cargo.toml;
448+
info "VSCode extension: cargo test";
449+
cargo test --manifest-path=../extensions/VSCode/Cargo.toml;
431450
info "cargo test";
432451
cargo test;
433452
)?;
@@ -458,6 +477,12 @@ fn run_client_build(
458477
// checks.
459478
skip_check_errors: bool,
460479
) -> io::Result<()> {
480+
// Ensure the JavaScript data structured generated from Rust are up to date.
481+
run_cmd!(
482+
info "cargo test export_bindings";
483+
cargo test export_bindings;
484+
)?;
485+
461486
let esbuild = PathBuf::from_slash("node_modules/.bin/esbuild");
462487
let distflag = if dist { "--minify" } else { "--sourcemap" };
463488
// This makes the program work from either the `server/` or `client/`
@@ -549,6 +574,13 @@ fn run_extensions_build(
549574
// directories.
550575
let rel_path = "../extensions/VSCode";
551576

577+
// The NAPI build.
578+
let mut napi_args = vec!["napi", "build", "--platform", "--output-dir", "src"];
579+
if dist {
580+
napi_args.push("--release");
581+
}
582+
run_script("npx", &napi_args, rel_path, true)?;
583+
552584
// The main build for the Client.
553585
run_script(
554586
&esbuild,
@@ -561,6 +593,11 @@ fn run_extensions_build(
561593
"--external:vscode",
562594
"--outdir=./out",
563595
distflag,
596+
// The binaries produced by NAPI-RS should be copied over.
597+
"--loader:.node=copy",
598+
// Avoid the default of adding hash names to the `.node` file
599+
// generated.
600+
"--asset-names=[name]",
564601
],
565602
rel_path,
566603
true,
@@ -578,10 +615,12 @@ fn run_extensions_build(
578615
}
579616

580617
fn run_change_version(new_version: &String) -> io::Result<()> {
618+
let cargo_regex = r#"(\r?\nversion = ")[\d.]+("\r?\n)"#;
581619
let replacement_string = format!("${{1}}{new_version}${{2}}");
620+
search_and_replace_file("Cargo.toml", cargo_regex, &replacement_string)?;
582621
search_and_replace_file(
583-
"Cargo.toml",
584-
r#"(\r?\nversion = ")[\d.]+("\r?\n)"#,
622+
"../extensions/VSCode/Cargo.toml",
623+
cargo_regex,
585624
&replacement_string,
586625
)?;
587626
search_and_replace_file(
@@ -601,18 +640,20 @@ fn run_prerelease() -> io::Result<()> {
601640
// Clean out all bundled files before the rebuild.
602641
remove_dir_all_if_exists("../client/static/bundled")?;
603642
run_install(true)?;
604-
run_cmd!(
605-
info "cargo test export_bindings";
606-
cargo test export_bindings;
607-
)?;
608-
run_script("pnpm", &["run", "dist"], "../client", true)?;
609-
Ok(())
643+
run_client_build(true, false)
610644
}
611645

612646
fn run_postrelease(target: &str) -> io::Result<()> {
613-
let server_dir = "../extensions/VSCode/server";
614-
// Only clean the `server/` directory if it exists.
615-
remove_dir_all_if_exists(server_dir)?;
647+
// Copy all the Client static files needed by the embedded Server to the
648+
// VSCode extension.
649+
let client_static_dir = "../extensions/VSCode/static";
650+
remove_dir_all_if_exists(client_static_dir)?;
651+
quick_copy_dir("../client/static/", client_static_dir, None)?;
652+
copy_file("log4rs.yml", "../extensions/VSCode/log4rs.yml")?;
653+
copy_file(
654+
"hashLocations.json",
655+
"../extensions/VSCode/hashLocations.json",
656+
)?;
616657

617658
// Translate from the target triple to VSCE's target parameter.
618659
let vsce_target = match target {
@@ -622,13 +663,6 @@ fn run_postrelease(target: &str) -> io::Result<()> {
622663
"aarch64-apple-darwin" => "darwin-arm64",
623664
_ => panic!("Unsupported platform {target}."),
624665
};
625-
626-
let src_name = format!("codechat-editor-server-{target}");
627-
quick_copy_dir(
628-
format!("../target/distrib/{src_name}/").as_str(),
629-
"../extensions/VSCode/server",
630-
None,
631-
)?;
632666
run_script(
633667
"npx",
634668
&[

extensions/VSCode/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,9 @@ out/
2626
# Server
2727
server/
2828

29+
# NAPI-RS
30+
src/index.d.ts
31+
src/index.js
32+
src/codechat-editor-client.win32-x64-msvc.node
33+
2934
# CodeChat Editor lexer: python. See TODO.

extensions/VSCode/Cargo.toml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Copyright (C) 2025 Bryan A. Jones.
2+
#
3+
# This file is part of the CodeChat Editor.
4+
#
5+
# The CodeChat Editor is free software: you can redistribute it and/or modify it
6+
# under the terms of the GNU General Public License as published by the Free
7+
# Software Foundation, either version 3 of the License, or (at your option) any
8+
# later version.
9+
#
10+
# The CodeChat Editor is distributed in the hope that it will be useful, but
11+
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13+
# details.
14+
#
15+
# You should have received a copy of the GNU General Public License along with
16+
# the CodeChat Editor. If not, see
17+
# [http://www.gnu.org/licenses/](http://www.gnu.org/licenses/).
18+
#
19+
# `Cargo.toml` -- Rust interface for the VSCode extension
20+
# =======================================================
21+
#
22+
# General package configurations
23+
# ------------------------------
24+
[package]
25+
authors = ["Bryan A. Jones", "Peter Loux"]
26+
categories = ["development-tools", "text-editors"]
27+
description = "A programmer's word processor."
28+
edition = "2024"
29+
homepage = "https://codechat-editor.onrender.com/fw/fsb/opt/render/project/src/README.md"
30+
keywords = ["literate programming"]
31+
license = "GPL-3.0-only"
32+
name = "codechat-editor-vscode-extension"
33+
readme = "../README.md"
34+
repository = "https://github.com/bjones1/CodeChat_Editor"
35+
version = "0.1.34"
36+
37+
[lib]
38+
crate-type = ["cdylib"]
39+
40+
[dependencies]
41+
actix-server = "2.6.0"
42+
codechat-editor-server = { path = "../../server" }
43+
log = "0.4.28"
44+
napi = { version = "3.0.0", features = ["tokio_rt"] }
45+
napi-derive = "3.0.0"
46+
tokio = "1.47.1"
47+
48+
[build-dependencies]
49+
napi-build = "2"
50+
51+
[profile.release]
52+
codegen-units = 1
53+
lto = true
54+
panic = "abort"
55+
strip = "symbols"

extensions/VSCode/build.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
napi_build::setup();
3+
}

extensions/VSCode/package.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@
2121
],
2222
"license": "GPL-3.0-only",
2323
"main": "out/extension.js",
24+
"napi": {
25+
"binaryName": "codechat-editor-client",
26+
"targets": [
27+
"x86_64-pc-windows-msvc",
28+
"x86_64-apple-darwin",
29+
"x86_64-unknown-linux-gnu",
30+
"aarch64-apple-darwin"
31+
]
32+
},
2433
"name": "codechat-editor-client",
2534
"prettier": {
2635
"tabWidth": 4
@@ -82,17 +91,23 @@
8291
"ws": "^8.18.3"
8392
},
8493
"devDependencies": {
94+
"@emnapi/core": "^1.5.0",
95+
"@emnapi/runtime": "^1.5.0",
96+
"@napi-rs/cli": "^3.2.0",
97+
"@tybys/wasm-util": "^0.10.1",
8598
"@types/escape-html": "^1.0.4",
8699
"@types/vscode": "1.61.0",
87100
"@types/ws": "^8.18.1",
88101
"@typescript-eslint/eslint-plugin": "^8.43.0",
89102
"@typescript-eslint/parser": "^8.43.0",
90103
"@vscode/vsce": "^3.6.0",
104+
"chalk": "^5.6.2",
91105
"esbuild": "^0.25.9",
92106
"eslint": "^9.35.0",
93107
"eslint-config-prettier": "^10.1.8",
94108
"eslint-plugin-import": "^2.32.0",
95109
"eslint-plugin-node": "^11.1.0",
110+
"npm-run-all2": "^8.0.4",
96111
"ovsx": "^0.10.5",
97112
"prettier": "^3.6.2",
98113
"typescript": "^5.9.2"

0 commit comments

Comments
 (0)