From a8cbabeb1412521d6a2902eb9d7e0a8948976657 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Wed, 21 Jun 2023 16:04:19 -0700 Subject: [PATCH 001/103] refactor: Start switch to pure rust --- Cargo.lock | 238 +------------------- Cargo.toml | 6 +- build.rs | 112 ---------- package.json | 15 -- services/Cargo.toml | 9 + services/chat.js | 28 --- services/dotreplit.js | 18 -- services/exec.js | 164 -------------- services/fsevents.js | 66 ------ services/gcsfiles.js | 69 ------ services/git.js | 72 ------ services/lsp2.js | 69 ------ services/null.js | 10 - services/open.js | 16 -- services/ot.js | 257 --------------------- services/presence.js | 83 ------- services/shell.js | 61 ----- services/shellrun2.js | 100 --------- services/snapshot.js | 14 -- services/src/main.rs | 3 + services/toolchain.js | 31 --- src/api.js | 11 - src/database.rs | 4 +- src/lib.rs | 3 - src/main.rs | 132 ++++++----- src/parse_paseto.rs | 20 +- src/repldb_server.rs | 4 +- src/replspace_server.rs | 6 +- src/runtime.js | 480 ---------------------------------------- src/services_debug.rs | 16 -- src/services_release.rs | 33 --- tsconfig.json | 22 -- yarn.lock | 149 ------------- 33 files changed, 113 insertions(+), 2208 deletions(-) delete mode 100644 package.json create mode 100644 services/Cargo.toml delete mode 100644 services/chat.js delete mode 100644 services/dotreplit.js delete mode 100644 services/exec.js delete mode 100644 services/fsevents.js delete mode 100644 services/gcsfiles.js delete mode 100644 services/git.js delete mode 100644 services/lsp2.js delete mode 100644 services/null.js delete mode 100644 services/open.js delete mode 100644 services/ot.js delete mode 100644 services/presence.js delete mode 100644 services/shell.js delete mode 100644 services/shellrun2.js delete mode 100644 services/snapshot.js create mode 100644 services/src/main.rs delete mode 100644 services/toolchain.js delete mode 100644 src/api.js delete mode 100644 src/runtime.js delete mode 100644 src/services_debug.rs delete mode 100644 src/services_release.rs delete mode 100644 tsconfig.json delete mode 100644 yarn.lock diff --git a/Cargo.lock b/Cargo.lock index 19361ae..29733fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,7 +265,7 @@ checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" dependencies = [ "borsh-derive-internal", "borsh-schema-derive-internal", - "proc-macro-crate 0.1.5", + "proc-macro-crate", "proc-macro2", "syn 1.0.109", ] @@ -422,12 +422,6 @@ dependencies = [ "os_str_bytes", ] -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - [[package]] name = "core-foundation" version = "0.9.3" @@ -518,12 +512,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "data-encoding" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" - [[package]] name = "deadqueue" version = "0.2.4" @@ -534,61 +522,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "deno_core" -version = "0.191.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "495704f95457631b366e8cbf427f817db8cdaf4b17832c69faa6b5b91e58fa2a" -dependencies = [ - "anyhow", - "bytes", - "deno_ops", - "futures", - "indexmap", - "libc", - "log", - "once_cell", - "parking_lot 0.12.1", - "pin-project", - "serde", - "serde_json", - "serde_v8", - "smallvec", - "sourcemap", - "tokio", - "url", - "v8", -] - -[[package]] -name = "deno_ops" -version = "0.69.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "511999e75fa5712d483a40811e8b600964893ddf3948d20e0aecf7dac6a1969f" -dependencies = [ - "lazy-regex", - "once_cell", - "pmutil", - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "regex", - "syn 1.0.109", -] - -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version 0.4.0", - "syn 1.0.109", -] - [[package]] name = "digest" version = "0.10.7" @@ -795,16 +728,6 @@ dependencies = [ "libc", ] -[[package]] -name = "fslock" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57eafdd0c16f57161105ae1b98a1238f97645f2f588438b2949c99a2af9616bf" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "funty" version = "2.0.0" @@ -1073,13 +996,13 @@ dependencies = [ name = "homeval" version = "0.2.0" dependencies = [ + "anyhow", "axum", "base64 0.21.2", "chrono", "chrono-tz", "cpu-time", "deadqueue", - "deno_core", "entity", "env_logger", "futures", @@ -1220,12 +1143,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "if_chain" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" - [[package]] name = "include_directory" version = "0.1.1" @@ -1370,29 +1287,6 @@ dependencies = [ "libc", ] -[[package]] -name = "lazy-regex" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff63c423c68ea6814b7da9e88ce585f793c87ddd9e78f646970891769c8235d4" -dependencies = [ - "lazy-regex-proc_macros", - "once_cell", - "regex", -] - -[[package]] -name = "lazy-regex-proc_macros" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8edfc11b8f56ce85e207e62ea21557cfa09bb24a8f6b04ae181b086ff8611c22" -dependencies = [ - "proc-macro2", - "quote", - "regex", - "syn 1.0.109", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -1601,7 +1495,6 @@ dependencies = [ "autocfg", "num-integer", "num-traits", - "rand 0.8.5", ] [[package]] @@ -1892,17 +1785,6 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" -[[package]] -name = "pmutil" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3894e5d549cccbe44afecf72922f277f603cd4bb0219c8342631ef18fffbe004" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "portable-pty" version = "0.8.1" @@ -1949,16 +1831,6 @@ dependencies = [ "toml 0.5.11", ] -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit", -] - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -2326,24 +2198,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver 1.0.17", -] - [[package]] name = "rustix" version = "0.37.20" @@ -2617,27 +2471,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" version = "1.0.164" @@ -2647,15 +2480,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde_bytes" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294" -dependencies = [ - "serde", -] - [[package]] name = "serde_derive" version = "1.0.164" @@ -2682,7 +2506,6 @@ version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" dependencies = [ - "indexmap", "itoa", "ryu", "serde", @@ -2718,22 +2541,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_v8" -version = "0.102.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b80e857f45543c24c52f62bbccf138d2a9715a17d3bde69e697fc261ae655ac" -dependencies = [ - "bytes", - "derive_more", - "num-bigint", - "serde", - "serde_bytes", - "smallvec", - "thiserror", - "v8", -] - [[package]] name = "serial" version = "0.4.0" @@ -2776,6 +2583,13 @@ dependencies = [ "serial-core", ] +[[package]] +name = "services" +version = "0.1.0" +dependencies = [ + "anyhow", +] + [[package]] name = "sha1" version = "0.10.5" @@ -2875,21 +2689,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "sourcemap" -version = "6.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed16231c92d0a6f0388f56e0ab2be24ecff1173f8e22f0ea5e074d0525631cb" -dependencies = [ - "data-encoding", - "if_chain", - "rustc_version 0.2.3", - "serde", - "serde_json", - "unicode-id", - "url", -] - [[package]] name = "spin" version = "0.5.2" @@ -3486,12 +3285,6 @@ version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" -[[package]] -name = "unicode-id" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d70b6494226b36008c8366c288d77190b3fad2eb4c10533139c1c1f461127f1a" - [[package]] name = "unicode-ident" version = "1.0.9" @@ -3534,7 +3327,6 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", - "serde", ] [[package]] @@ -3552,18 +3344,6 @@ dependencies = [ "serde", ] -[[package]] -name = "v8" -version = "0.73.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1bd3f04ba5065795dae6e3db668ff0b628920fbd2e39c1755e9b62d93660c3c" -dependencies = [ - "bitflags", - "fslock", - "once_cell", - "which", -] - [[package]] name = "value-bag" version = "1.0.0-alpha.9" diff --git a/Cargo.toml b/Cargo.toml index ab991b2..b4f9b1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ description = """A custom implementation of replits evaluation protocol. See https://govaldocs.pages.dev""" [workspace] -members = [".", "migration", "entity"] +members = [".", "migration", "entity", "services"] [features] default = ["replspace", "database", "repldb", "verify_connections"] @@ -20,7 +20,7 @@ fun-stuff = ["dep:chrono", "dep:chrono-tz"] verify_connections = ["dep:pasetors", "dep:hyper", "dep:hyper-tls"] [dependencies] -deno_core = "0.191.0" +# deno_core = "0.191.0" env_logger = { git = "https://github.com/tmccombs/env_logger", rev = "a47d1d99", features=["kv_unstable"] } futures-channel = "0.3.26" futures-util = "0.3.26" @@ -59,7 +59,7 @@ sea-query = { version = "0.28.5", optional = true } pasetors = { version = "0.6.7", default-features = false, features = ["v2"], optional = true } hyper = { version = "0.14.26", features = ["http1", "http2", "client"], optional = true } hyper-tls = { version = "0.5.0", optional = true } +anyhow = "1.0.71" [build-dependencies] prost-build = "0.11.8" -deno_core = { version = "0.191.0", features = ["include_js_files_for_snapshotting"] } diff --git a/build.rs b/build.rs index c9a12be..b9d963c 100644 --- a/build.rs +++ b/build.rs @@ -1,14 +1,8 @@ -use std::{path::PathBuf, process::Command}; - -use deno_core::Extension; use prost_build::Config; extern crate prost_build; fn main() { - // Only rerun if a protobuf changed, or api.js/package.json is changed println!("cargo:rerun-if-changed=src/protobufs"); - println!("cargo:rerun-if-changed=src/api.js"); - println!("cargo:rerun-if-changed=src/runtime.js"); println!("cargo:rerun-if-changed=package.json"); @@ -22,110 +16,4 @@ fn main() { config .compile_protos(&["src/protobufs/goval.proto"], &["src/"]) .unwrap(); - - let output; - let runner; - if cfg!(target_os = "windows") { - // Run: yarn install - output = Command::new("cmd") - .arg("/C") - .arg("yarn install --pure-lockfile") - .output() - .expect("Getting yarn output failed"); - runner = "yarn"; - } else { - // Run: bun install - output = Command::new("bun") - .arg("install") - .arg("-y") - .output() - .expect("Getting bun output failed"); - runner = "bun"; - } - - assert!(output.status.success(), "Running {} install failed", runner); - - let out_file = format!("--outfile={}/api.js", std::env::var("OUT_DIR").unwrap()); - - let mut esbuild_args = vec![ - "esbuild", - "src/api.js", - "--bundle", - "--minify", - "--platform=browser", - &out_file, - ]; - - let output; - let runner; - if cfg!(target_os = "windows") { - // Run: npx esbuild ... - let mut cmd_arg = vec!["npx"]; - cmd_arg.append(&mut esbuild_args); - output = Command::new("cmd") - .arg("/C") - .arg(cmd_arg.join(" ")) - .output() - .expect("Getting `npx esbuild ...` output failed"); - runner = "npx"; - } else { - // Run: bun x esbuild ... - output = Command::new("bun") - .arg("x") - .args(esbuild_args) - .output() - .expect("Getting `bun x esbuild ...` output failed"); - runner = "bun"; - } - - assert!( - output.status.success(), - "Running esbuild via {} failed", - runner - ); - - // TODO: snapshot api.js as well - let homeval_extension = Extension::builder("homeval") - .js( - vec![ - deno_core::ExtensionFileSource { - specifier: concat!("ext:homeval", "/", "src/runtime.js"), - code: deno_core::ExtensionFileSourceCode::LoadedFromFsDuringSnapshot( - std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("src/runtime.js"), - ), - }, - deno_core::ExtensionFileSource { - specifier: concat!("ext:homeval", "/", "gen/api.js"), - code: deno_core::ExtensionFileSourceCode::LoadedFromFsDuringSnapshot( - std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap()).join("api.js"), - ), - }, - ], - // include_js_files!(homeval "src/runtime.js",), - ) - .build(); - - // Build the file path to the snapshot. - let out_dir = PathBuf::from(std::env::var_os("OUT_DIR").unwrap()); - let snapshot_path = out_dir.join("HOMEVAL_JS_SNAPSHOT.bin"); - - // Create the snapshot. - for file in - deno_core::snapshot_util::create_snapshot(deno_core::snapshot_util::CreateSnapshotOptions { - cargo_manifest_dir: env!("CARGO_MANIFEST_DIR"), - snapshot_path, - startup_snapshot: None, - extensions: vec![homeval_extension], - compression_cb: None, - snapshot_module_load_cb: None, - }) - .files_loaded_during_snapshot - { - let path = file.into_os_string().into_string().unwrap(); - if path.contains("api.js") { - continue; - } - - println!("cargo:rerun-if-changed={}", path) - } } diff --git a/package.json b/package.json deleted file mode 100644 index 23e2106..0000000 --- a/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "plugandplaygoval", - "version": "1.0.0", - "main": "index.js", - "author": "PotentialStyx <62217716+PotentialStyx@users.noreply.github.com>", - "license": "MIT", - "private": true, - "dependencies": { - "@replit/protocol": "^0.3.12", - "buffer": "^6.0.3", - "crc-32": "^1.2.2", - "fastestsmallesttextencoderdecoder": "^1.0.22", - "protobufjs": "^7.2.3" - } -} diff --git a/services/Cargo.toml b/services/Cargo.toml new file mode 100644 index 0000000..8f77204 --- /dev/null +++ b/services/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "services" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.71" diff --git a/services/chat.js b/services/chat.js deleted file mode 100644 index 66e7c2e..0000000 --- a/services/chat.js +++ /dev/null @@ -1,28 +0,0 @@ -// console.log(globalThis.ServiceBase, globalThis.cookie, globalThis.cookie1, console.log) -// console.mod() -class Service extends ServiceBase { - constructor(...args) { - super(...args) - this.history = []; - } - - async recv(cmd, session) { - if (cmd.chatMessage) { - this.history.push(cmd.chatMessage) - this.send({chatMessage: cmd.chatMessage}, -session) - } else if (cmd.chatTyping) { - this.send({chatTyping: cmd.chatTyping}, -session) - } - } - - async attach(session) { - this.send({chatScrollback: {scrollback:this.history}}, session) - } -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() diff --git a/services/dotreplit.js b/services/dotreplit.js deleted file mode 100644 index 7d6d422..0000000 --- a/services/dotreplit.js +++ /dev/null @@ -1,18 +0,0 @@ -class Service extends ServiceBase { - constructor(...args) { - super(...args) - this.config = process.getDotreplitConfig() - } - async recv(cmd, _session) { - if (cmd.dotReplitGetRequest) { - return api.Command.create({dotReplitGetResponse: {dotReplit: this.config}}) - } - } -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() diff --git a/services/exec.js b/services/exec.js deleted file mode 100644 index 336f778..0000000 --- a/services/exec.js +++ /dev/null @@ -1,164 +0,0 @@ -class Service extends ServiceBase { - constructor(...args) { - super(...args) - this.running = false - this.proc = null - this.queue = [] - - this.dead_procs = [] - this.current_ref = null - } - - async recv(cmd, session) { - if (cmd.input) { - await this.proc.write(cmd.input) - } else if (cmd.exec) { - let invalid = await this.validate_exec(cmd.exec) - if (invalid) { - return invalid - } - - if (this.running) { - const is_blocking = cmd.exec.blocking || (cmd.exec.lifecycle === api.Exec.Lifecycle.BLOCKING) - - if (!is_blocking) { - return api.Command.create({error: "Already running"}) - } - - this.queue.push(cmd) - return - } - - this.current_ref = cmd.ref - await this.start_proc(cmd.exec) - } else { - console.debug("Unknown exec msg", cmd) - } - } - - async process_dead(proc_id, exit_code) { - if (this.dead_procs.includes(proc_id) && proc_id !== -1) {return} - this.dead_procs.push(proc_id) - this.running = false - - if (proc_id !== -1) { - try { - await this.proc.destroy() - } catch (_) {} - } - - await this.send(api.Command.create({state: api.State.Stopped}), 0) - - let final_exit = api.Command.create({ok: {}}) - if (exit_code !== 0) { - final_exit = api.Command.create({error: `exit status ${exit_code}`}) - } - - final_exit.ref = this.current_ref - await this.send(final_exit, 0) - - - this.current_ref = null - if (this.queue.length === 0) { - return - } - - let cmd = this.queue.shift(); - this.current_ref = cmd.ref - await this.start_proc(cmd.exec) - } - - async validate_exec(cmd) { - if (cmd.args.length === 0) { - return api.Command.create({error: "Missing command"}) - } - return false - } - - async resource_usage(cmd) { - const is_cpu_req = cmd === "date '+%s%N' && cat /sys/fs/cgroup/cpu/cpuacct.usage /sys/fs/cgroup/cpu/cpu.cfs_quota_us /sys/fs/cgroup/cpu/cpu.cfs_period_us /sys/fs/cgroup/memory/memory.usage_in_bytes /sys/fs/cgroup/memory/memory.soft_limit_in_bytes /sys/fs/cgroup/memory/memory.limit_in_bytes &&grep '^\\(total_rss\\|total_cache\\) ' /sys/fs/cgroup/memory/memory.stat"; - const is_storage_req = cmd === "cat /repl/stats/subvolume_usage_bytes /repl/stats/subvolume_total_bytes /repl/stats/scratch_usage_bytes /repl/stats/scratch_total_bytes"; - // if (is_cpu_req) { - // return "date '+%s%N' && echo 100000 && echo 200000 && cat /sys/fs/cgroup/cpu/cpu.cfs_period_us /sys/fs/cgroup/memory/memory.usage_in_bytes /sys/fs/cgroup/memory/memory.soft_limit_in_bytes /sys/fs/cgroup/memory/memory.limit_in_bytes &&grep '^\\(total_rss\\|total_cache\\) ' /sys/fs/cgroup/memory/memory.stat"; - // } else - if (is_cpu_req || is_storage_req) { - await this.send(api.Command.create({state: api.State.Running}), 0) - let output = ""; - - if (is_storage_req) { - const disk = await process.system.diskUsage(); - output = `${disk.free}\n${disk.total}\n0\n0\n` - } - if (is_cpu_req) { - const cpuTime = await process.system.cpuTime(); - const memory = await process.system.memoryUsage(); - const memoryUsage = memory.total - memory.free; - const totalMemory = memory.total - output = `${new Number(Date.now()) * 1000000}\n${cpuTime}\n200000\n100000\n${memoryUsage}\n${totalMemory}\n${totalMemory}\ntotal_cache 0\ntotal_rss ${memoryUsage}` - } - - await this.send(api.Command.create({output}), 0) - - await this.process_dead(-1, 0) - - return false - } else { - return cmd - } - } - - async start_proc(msg) { - this.running = true - // TODO: splitLogs, splitStderr - let cmd = msg.args[0]; - let env = msg.env ? msg.env : {}; - env.REPLIT_GIT_TOOLS_CHANNEL_FROM = this.id.toString() - - if (msg.args.length === 3 && msg.args[1] === "-c") { - const search = "rg --json --context 0 --fixed-strings" - if (cmd === "bash") { - let arg = msg.args[2] - - let new_cmd = await this.resource_usage(arg) - if (new_cmd) { - msg.args[2] = new_cmd - } else { - return - } - } else if (cmd === "sh") { - if (msg.args[2].slice(0, search.length) === search) { - await this.send(api.Command.create({state: api.State.Running}), 0) - msg.args[0] = "bash" - const exit = await process.quickCommand(msg.args, this.id, this.clients, env) - - await this.process_dead(-1, exit) - return - } - } - - } - - const args = msg.args.slice(1) - - await this.send(api.Command.create({state: api.State.Running}), 0) - this.proc = new Process(this.id, cmd, args, env) - - await this.proc.init(this.clients) - - } - - async attach(session) { - if (this.proc) await this.proc.add_session(session) - } - - async detach(session) { - if (this.proc) await this.proc.remove_session(session) - } -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() diff --git a/services/fsevents.js b/services/fsevents.js deleted file mode 100644 index c0a87bb..0000000 --- a/services/fsevents.js +++ /dev/null @@ -1,66 +0,0 @@ -class Service extends ServiceBase { - constructor(...args) { - super(...args); - this.watcher = new FileWatcher(); - this.watcher.add_listener(this.file_event.bind(this)); - this.watcher.init(); - this.watcher.start().catch((err) => { - throw err; - }); - } - - async shutdown() { - await this.watcher.stop() - } - - async file_event(event) { - let op; - let file; - let dest; - - if (event.remove) { - file = event.remove; - op = api.FileEvent.Op.Remove; - } else if (event.create) { - file = event.create; - op = api.FileEvent.Op.Create; - } else if (event.modify) { - file = event.modify; - op = api.FileEvent.Op.Modify; - } else if (event.rename) { - file = event.rename[0]; - dest = event.rename[1]; - - op = api.FileEvent.Op.Move; - } else { - console.error("Unknown fsevent:", event) - return - } - - this.send( - api.Command.create({ - fileEvent: { - op, - file: { path: file }, - dest: { path: dest } - }, - }), - 0, - ); - } - - async recv(cmd, _session) { - if (cmd.subscribeFile) { - // TODO: stat file to see if it really exists - await this.watcher.watch(cmd.subscribeFile.files.map(e => e.path)); - return api.Command.create({ok: {}}) - } - } -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start(); diff --git a/services/gcsfiles.js b/services/gcsfiles.js deleted file mode 100644 index 0cb24cd..0000000 --- a/services/gcsfiles.js +++ /dev/null @@ -1,69 +0,0 @@ -class Service extends ServiceBase { - async recv(cmd, session) { - if (cmd.readdir) { - let files = [] - - try { - files = await fs.readDir(cmd.readdir.path) - } catch(err) { - return api.Command.create({error: err.toString()}) - } - - return api.Command.create({ - files: { files: files.map(item => {return {path: item.path, type: item.type !== "directory" ? api.File.Type.FILE : api.File.Type.DIRECTORY}}) }, - }); - } else if (cmd.mkdir) { - await fs.makeDir(cmd.mkdir.path) - return api.Command.create({ok: {}}) - } else if (cmd.write) { - let contents = cmd.write.content - if (contents.length === 0) { - contents = [] - } - await fs.writeFile(cmd.write.path, contents) - return api.Command.create({ok:{}}) - } else if (cmd.read) { - let contents; - if (cmd.read.path === ".config/goval/info") { - const encoder = new TextEncoder(); - contents = encoder.encode(JSON.stringify({ - "server": process.server.name(), - "version": process.server.version(), - "license": process.server.license(), - "authors": process.server.authors(), - "repository": process.server.repository(), - "description": process.server.description(), - "uptime": process.server.uptime(), - "services": process.server.services() - })) - } else { - const fstat = await fs.stat(cmd.read.path); - - if (!fstat.exists) { - return api.Command.create({error: `${cmd.read.path}: no such file or directory`}) - } - - contents = await fs.readFile(cmd.read.path); - } - - return api.Command.create({file:{path:cmd.read.path, content: contents}}) - } else if (cmd.remove) { - await fs.remove(cmd.remove.path) - return api.Command.create({ok:{}}) - } else if (cmd.move) { - await fs.rename(cmd.move.oldPath, cmd.move.newPath) - return api.Command.create({ok:{}}) - } else if (cmd.stat) { - return api.Command.create({statRes: await fs.stat(cmd.stat.path)}) - } else { - console.warn("Unknown gcsfiles cmd", cmd) - } - } -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() \ No newline at end of file diff --git a/services/git.js b/services/git.js deleted file mode 100644 index b1fa1a2..0000000 --- a/services/git.js +++ /dev/null @@ -1,72 +0,0 @@ -// TODO: actually implement this service -// It is used on replit when xdg-open is used -// to make a connected client open the files -// It only sends messages never recv's them so -// a blank service impl is fine. - -class Service extends ServiceBase { - constructor(...args) { - super(...args) - - this.send_reply = {} - } - - async recv(cmd, _session) { - if (cmd.replspaceApiGitHubToken) { - const nonce = cmd.replspaceApiGitHubToken.nonce - const token = cmd.replspaceApiGitHubToken.token - - await this.replspace_reply(nonce, {githubTokenRes: token}); - } else if (cmd.replspaceApiCloseFile) { - const nonce = cmd.replspaceApiCloseFile.nonce - const send = this.send_reply[nonce]; - - if (!send) { - return - } - - await this.replspace_reply(nonce, {openFileRes: {}}); - } else { - console.debug("Unknown message:", cmd) - } - } - - async on_replspace(session, msg) { - let real_session = session - if (session === 0) { - // Basically we have no clue who its for so just send it to someone /shrug - real_session = this.clients[Math.floor(Math.random()*this.clients.length)] - } - - if (msg.githubTokenReq) { - const nonce = msg.githubTokenReq; - - await this.send(api.Command.create({replspaceApiGetGitHubToken: {nonce}}), real_session); - } else if (msg.openFileReq) { - // (file, wait for close, nonce) - const path = msg.openFileReq[0]; - const wait_close = msg.openFileReq[1]; - const nonce = msg.openFileReq[2]; - - const cmd = api.Command.create({ - replspaceApiOpenFile: { - nonce, - waitForClose: wait_close, - file: path - } - }); - - this.send_reply[nonce] = wait_close - await this.send(cmd, real_session) - } else { - console.warn("Unknown replspace message:", msg) - } - } -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() diff --git a/services/lsp2.js b/services/lsp2.js deleted file mode 100644 index 7f7ea56..0000000 --- a/services/lsp2.js +++ /dev/null @@ -1,69 +0,0 @@ -class Service extends ServiceBase { - constructor(...args) { - super(...args) - this.running = false - this.proc = null - - this.dead_procs = [] - - this.config = process.getDotreplitConfig() - } - - async recv(cmd, session) { - if (cmd.input) { - await this.proc.write(cmd.input) - } else if (cmd.startLSP) { - if (this.running) { - return api.Command.create({error: "LSP already running"}) - return - } - - this.current_ref = cmd.ref - this.running = true - - const _args = this.config.languages[cmd.startLSP.languageServerId].languageServer.start.args - - const runcmd = _args[0]; - const args = _args.slice(1) - - - this.proc = new Process(this.id, runcmd, args, {}) - - await this.proc.init(this.clients) - await this.send(api.Command.create({ok: {}, ref: cmd.ref}), 0) - - } else { - console.debug("Unknown LSP msg", cmd) - - } - } - - async process_dead(proc_id, exit_code) { - if (this.dead_procs.includes(proc_id) && proc_id !== -1) {return} - this.dead_procs.push(proc_id) - this.running = false - - if (proc_id !== -1) { - try { - await this.proc.destroy() - } catch (_) {} - } - - await this.send(api.Command.create({state: api.State.Stopped}), 0) - } - - async attach(session) { - if (this.proc) await this.proc.add_session(session) - } - - async detach(session) { - if (this.proc) await this.proc.remove_session(session) - } -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() diff --git a/services/null.js b/services/null.js deleted file mode 100644 index f48f142..0000000 --- a/services/null.js +++ /dev/null @@ -1,10 +0,0 @@ -class Service extends ServiceBase { - async recv(_cmd, _session) {} -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() diff --git a/services/open.js b/services/open.js deleted file mode 100644 index 4cae26e..0000000 --- a/services/open.js +++ /dev/null @@ -1,16 +0,0 @@ -// TODO: actually implement this service -// It is used on replit when xdg-open is used -// to make a connected client open the files -// It only sends messages never recv's them so -// a blank service impl is fine. - -class Service extends ServiceBase { - async recv(_cmd, _session) {} -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() diff --git a/services/ot.js b/services/ot.js deleted file mode 100644 index 5996d95..0000000 --- a/services/ot.js +++ /dev/null @@ -1,257 +0,0 @@ -class Service extends ServiceBase { - constructor(...args) { - super(...args); - this.version = 1 - this.contents = "" - this.path = null - this.cursors = {} - this.history = [] - this.session_info = {} - - this.watcher = new FileWatcher(); - this.watcher.add_listener(this.file_event.bind(this)); - this.watcher.init(); - this.watcher.start().catch((err) => { - throw err; - }); - } - - async shutdown() { - await this.watcher.stop() - } - - async recv(cmd, session) { - if (!this.path && !cmd.otLinkFile) { - console.error("Command sent before otLinkFile", cmd) - return - } - - if (cmd.otLinkFile) { - const path = cmd.otLinkFile.file.path; - const fstat = await fs.stat(path); - - if (!fstat.exists) { - return api.Command.create({error: `${path}: no such file or directory`}) - } - - let db_file = null; - - if (process.database.supported) { - db_file = await process.database.getFile(path) - if (db_file) { - console.debug("Database has entry for file", path) - } else { - console.debug("Database missing entry for file", path) - } - } - - this.watcher.watch([path]) - - this.path = path - - const content = await fs.readFile(path); - const file_crc32 = CRC32.buf(content); - if (db_file) { - this.history = db_file.history.map(JSON.parse) - this.version = this.history.length - - if (db_file.crc32 !== file_crc32) { - this.contents = await fs.readFileString(path); - this.version += 1 - let diff = await diffText(db_file.contents, await fs.readFileString(this.path)) - - this.history.push({ - spookyVersion: this.version, - op: diff, - crc32: file_crc32, - committed: { - seconds: (Date.now()/ 1000n).toString(), - nanos: 0 - }, - version: this.version, - author: api.OTPacket.Author.USER, - // use https://replit.com/@homeval for diffed insert - userId: 23352071 - }) - } else { - this.contents = db_file.contents - } - } else { - this.contents = await fs.readFileString(path); - this.history = [{ - spookyVersion: this.version, - op: [{insert: this.contents}], - crc32: file_crc32, - committed: { - seconds: (Date.now()/ 1000n).toString(), - nanos: 0 - }, - version: this.version, - author: api.OTPacket.Author.USER, - // use https://replit.com/@homeval for initial insert - userId: 23352071 - }] - } - - await this.save_to_db(file_crc32, this.contents) - - - return api.Command.create({otLinkFileResponse:{version:this.version, linkedFile:{path, content}}}) - } else if (cmd.ot) { - let cursor = 0 - let contents = [...this.contents] - - for (const op of cmd.ot.op) { - if (op.skip) { - const skip = op.skip - if (skip + cursor > contents.length) { - throw new Error("Invalid skip past bounds") - } - - cursor += skip - } - if (op.insert) { - const insert = op.insert - contents = [...contents.slice(0, cursor), ...insert, ...contents.slice(cursor)] - cursor += insert.length - } - if (op.delete) { - const del = op.delete - if (del + cursor > contents.length) { - throw new Error("Invalid delete past bounds") - } - - contents = [...contents.slice(0,cursor), ...contents.slice(cursor + del)] - } - } - - const final_contents = contents.join("") - - this.version += 1 - this.contents = final_contents - - let userId = cmd.ot.userId; - - if (cmd.ot.author !== api.OTPacket.Author.GHOSTWRITER) { - if (this.session_info[session]) { - userId = this.session_info[session].id - } else { - userId = 0 - } - } else { - userId = 22261053 - } - - const crc32 = CRC32.str(final_contents); - - const inner_packet = { - spookyVersion: this.version, - op: cmd.ot.op, - crc32, - committed: { - seconds: (Date.now()/ 1000n).toString(), - nanos: 0 - }, - version: this.version, - author: cmd.ot.author, - // use https://replit.com/@ghostwriterai if ghostwriter wrote it (for history) - userId - } - - this.history.push(inner_packet) - - const msg = api.Command.create({ - ot: inner_packet - }) - - await this.send(msg, 0) - - await fs.writeFileString(this.path, final_contents) - - this.save_to_db(crc32, final_contents) - - return api.Command.create({ - ok: {} - }) - } else if (cmd.otNewCursor) { - const cursor = cmd.otNewCursor - this.cursors[cursor.id] = cursor - - const msg = api.Command.create({ otNewCursor: cursor }) - - await this.send(msg, -session) - } else if (cmd.otDeleteCursor) { - delete this.cursors[cmd.otDeleteCursor.id] - - const msg = api.Command.create({ otDeleteCursor: cmd.otDeleteCursor }) - - await this.send(msg, -session) - } else if (cmd.otFetchRequest) { - return api.Command.create({ - otFetchResponse: { - packets: this.history.slice( - cmd.otFetchRequest.versionFrom - 1, - cmd.otFetchRequest.versionTo + 1 - ) - } - }) - } else if (cmd.flush) { - return api.Command.create({ - ok: {} - }) - }else { - console.warn("Unknown ot command", cmd) - } - } - - async save_to_db(crc32, contents) { - if (process.database.supported) { - await process.database.setFile({ - history: this.history.map(JSON.stringify), - name: this.path, - contents, - crc32, - }) - } - } - - async file_event(event) { - if (event.modify === this.path) { - let diff = await diffText(this.contents, await fs.readFileString(this.path)) - if (diff.length === 0) { - return - } - - await this.recv(api.Command.create({ot:{op: diff}, author: api.OTPacket.Author.USER, userId: 0}), 0) - } else { - console.debug(event.modify, this.path, event) - } - } - - async attach(session) { - this.session_info[session] = await process.getUserInfo(session) - if (!this.path) { - await this.send(api.Command.create({otstatus: {}}), session) - return - } - - - - await this.send(api.Command.create({ - otstatus:{ - contents:this.contents, - version: this.version, - linkedFile: {path:this.path}, - cursors: Object.values(this.cursors) - } - }), session) - - } -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() diff --git a/services/presence.js b/services/presence.js deleted file mode 100644 index 5410167..0000000 --- a/services/presence.js +++ /dev/null @@ -1,83 +0,0 @@ -class Service extends ServiceBase { - constructor(...args) { - super(...args) - this.users = [] - this.files = {} - - this.session_map = {} - } - - async recv(cmd, session) { - if (cmd.followUser) { - await this.send(api.Command.create({followUser: {session}}), cmd.followUser.session) - } else if (cmd.unfollowUser) { - await this.send(api.Command.create({unfollowUser: {session}}), cmd.unfollowUser.session) - } else if (cmd.openFile) { - const user = this.session_map[session]; - - const msg = { - userId: user.id, - session, - timestamp: { - seconds: (Date.now()/ 1000n).toString(), - nanos: 0 - } - }; - - if (cmd.openFile.file) { - msg.file = cmd.openFile.file - } - - this.files[session] = msg - - await this.send(api.Command.create({fileOpened: msg}), -session) - } else { - console.debug("Unknown presence command:", cmd); - } - } - - async attach(session) { - const roster = api.Command.create({ - roster: { - user: this.users, - files: Object.values(this.files) - } - }) - - await this.send(roster, session) - - const _user = await process.getUserInfo(session); - - this.session_map[session] = _user; - - const user = { - id: _user.id, - name: _user.username, - session: session - } - - this.users.push(user) - - await this.send(api.Command.create({ join: user }), -session) - } - - async detach(session) { - const user = this.session_map[session]; - delete this.files[session]; - - await this.send(api.Command.create({ - part: { - id: user.id, - name: user.username, - session: session - } - }), -session) - } -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() diff --git a/services/shell.js b/services/shell.js deleted file mode 100644 index 9421eb9..0000000 --- a/services/shell.js +++ /dev/null @@ -1,61 +0,0 @@ -class Service extends ServiceBase { - constructor(...args) { - super(...args) - this.supported = process.system.os !== "windows" - - if (this.supported) { - this.pty = new PtyProcess(this.id, process.env.SHELL || "sh", [], { - "REPLIT_GIT_TOOLS_CHANNEL_FROM": this.id.toString() - }) - - this.pty.init(this.clients).then(_ => { - console.debug("shell pty obtained:", this.pty.id) - }) - this.dead_ptys = [] - } else { - console.warn("Shell isn't supported on windows") - } - - } - - async process_dead(pty) { - if (this.dead_ptys.includes(pty) || !this.supported) {return} - this.dead_ptys.push(pty) - - this.pty = new PtyProcess(this.id, process.env.SHELL || "sh", [], { - "REPLIT_GIT_TOOLS_CHANNEL_FROM": this.id.toString() - }); - - await this.pty.init(this.clients) - console.debug("shell pty obtained:", this.pty.id) - } - - async recv(cmd, session) { - if (cmd.input && this.supported) { - await this.pty.write(cmd.input) - } - } - - async attach(session) { - if (!this.supported) { - await this.send(api.Command.create({output:"\u001b[33m\u001b[39m Shell is not supported for homeval on windows right now."}), session) - return - } - - await this.pty.add_session(session) - - } - - async detach(session) { - if (this.supported) { - await this.pty.remove_session(session) - } - } -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() diff --git a/services/shellrun2.js b/services/shellrun2.js deleted file mode 100644 index 1f210f7..0000000 --- a/services/shellrun2.js +++ /dev/null @@ -1,100 +0,0 @@ -class Service extends ServiceBase { - constructor(...args) { - super(...args) - - this.supported = process.system.os !== "windows" - this.config = process.getDotreplitConfig() - - if (this.supported) { - this.running = false - this.dead_ptys = [] - this.pty = new PtyProcess(this.id, process.env.SHELL || "sh", [], { - "REPLIT_GIT_TOOLS_CHANNEL_FROM": this.id.toString() - }) - this.pty.init(this.clients).then(_ => { - console.debug("shell pty obtained:", this.pty.id) - }) - } else { - console.warn("Console isn't supported on windows") - } - } - - async recv(cmd, session) { - if (cmd.input && this.supported) { - await this.pty.write(cmd.input) - } else if (cmd.runMain) { - if (!this.supported) { - await this.send(api.Command.create({state: api.State.Running}), 0) - await this.send(api.Command.create({output:"\u001b[33m\u001b[39m Console is not supported for homeval on windows right now."}), 0) - await this.send(api.Command.create({state: api.State.Stopped}), 0) - } else if (!this.running) { - // TODO: see how official impl deals with runMain while running - this.dead_ptys.push(this.pty.id) - await this.pty.destroy() - this.running = true - - let cmd = "echo"; - let args = ["No run command set in your `.replit` file"] - if (this.config.run) { - cmd = this.config.run.args[0] - args = this.config.run.args.slice(1) - } - - this.pty = new PtyProcess(this.id, cmd, args, { - "REPLIT_GIT_TOOLS_CHANNEL_FROM": this.id.toString() - }) - await this.send(api.Command.create({output:"" + `\u001b[33m\u001b[39m ${cmd} ${args.join(" ")}\u001b[K\r\n\u001b[0m`}), 0) - await this.pty.init(this.clients) - console.debug("Running command now", this.pty.id) - await this.send(api.Command.create({state: api.State.Running}), 0) - } - } else if (cmd.clear && this.running) { - await this.pty.destroy() - } - } - - async attach(session) { - if (!this.supported) { - await this.send(api.Command.create({output:"\u001b[33m\u001b[39m Console is not supported for homeval on windows right now."}), session) - return; - } - - await this.pty.add_session(session) - await this.send( - api.Command.create({ - state: this.running ? api.State.Running : api.State.Stopped - }), - session - ) - } - - async detach(session) { - if (this.supported) { - await this.pty.remove_session(session) - } - } - - async process_dead(pty) { - if (this.dead_ptys.includes(pty) || !this.supported) {return} - this.dead_ptys.push(pty) - // - if (this.running) { - this.running = false - await this.send(api.Command.create({state: api.State.Stopped}), 0) - } else { - } - - try {await this.pty.destroy()} catch(err) {} - - this.pty = new PtyProcess(this.id, process.env.SHELL || "sh") - await this.pty.init(this.clients) - console.debug("shell pty obtained:", this.pty.id) - } -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() diff --git a/services/snapshot.js b/services/snapshot.js deleted file mode 100644 index cb5070f..0000000 --- a/services/snapshot.js +++ /dev/null @@ -1,14 +0,0 @@ -class Service extends ServiceBase { - async recv(cmd, _session) { - if (cmd.fsSnapshot) { // No handling needed as all changes are persisted to the local fs by the local fs, and ot writes instantly - return api.Command.create({ok: {}}) - } - } -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() diff --git a/services/src/main.rs b/services/src/main.rs new file mode 100644 index 0000000..e7a11a9 --- /dev/null +++ b/services/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} diff --git a/services/toolchain.js b/services/toolchain.js deleted file mode 100644 index 617f11d..0000000 --- a/services/toolchain.js +++ /dev/null @@ -1,31 +0,0 @@ -class Service extends ServiceBase { - constructor(...args) { - super(...args) - this.config = this.toolchainify(process.getDotreplitConfig()) - } - - toolchainify(input) { - let res = {entrypoint: input.entrypoint, languageServers: []} - - for (const [key, value] of Object.entries(input.languages ? input.languages : {})) { - res.languageServers.push( - {id: key, name: key, language: value.syntax || key, fileTypeAttrs: {filePattern: value.pattern}} - ); - } - - return res - } - - async recv(cmd, _session) { - if (cmd.toolchainGetRequest) { - return api.Command.create({toolchainGetResponse: {configs: this.config}}) - } - } -} - -const service = new Service( - serviceInfo.id, - serviceInfo.service, - serviceInfo.name, -); -await service.start() diff --git a/src/api.js b/src/api.js deleted file mode 100644 index 8a73ce5..0000000 --- a/src/api.js +++ /dev/null @@ -1,11 +0,0 @@ -import * as api from "@replit/protocol"; -import protobufjs from "protobufjs"; -import buffer from "buffer"; -import CRC32 from "crc-32" -import {TextEncoder} from 'fastestsmallesttextencoderdecoder'; - -globalThis.TextEncoder = TextEncoder -globalThis.api = api.replit.goval.api; -globalThis.Buffer = buffer.Buffer; -globalThis.protobufjs = protobufjs; -globalThis.CRC32 = CRC32 diff --git a/src/database.rs b/src/database.rs index 83c5da4..26c632e 100644 --- a/src/database.rs +++ b/src/database.rs @@ -1,4 +1,4 @@ -use deno_core::error::AnyError; +use anyhow::Result; use log::{debug, warn}; use migration::MigratorTrait; use sea_orm::{ConnectOptions, Database}; @@ -8,7 +8,7 @@ use tokio::sync::OnceCell; pub static DATABASE: OnceCell = OnceCell::const_new(); // TODO: allow disabling of db at runtime as well as compile time -pub async fn setup() -> Result<(), AnyError> { +pub async fn setup() -> Result<()> { let db_url; match std::env::var("HOMEVAL_DB") { diff --git a/src/lib.rs b/src/lib.rs index c1b936f..c9bc433 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,3 @@ pub mod goval { include!(concat!(env!("OUT_DIR"), "/goval.rs")); } - -pub static HOMEVAL_JS_SNAPSHOT: &[u8] = - include_bytes!(concat!(env!("OUT_DIR"), "/HOMEVAL_JS_SNAPSHOT.bin")); diff --git a/src/main.rs b/src/main.rs index 86c59ec..aa54227 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,6 @@ -use deno_extension::messaging::ReplspaceMessage; +// use deno_extension::messaging::ReplspaceMessage; use homeval::goval; +use serde::{Deserialize, Serialize}; use std::time::Instant; use std::{collections::HashMap, io::Error, sync::Arc}; @@ -10,21 +11,37 @@ use tokio::sync::{mpsc, Mutex, RwLock}; mod channels; use channels::IPCMessage; -mod deno_extension; -use deno_extension::{JsMessage, Service}; +// mod deno_extension; +// use deno_extension::{JsMessage, Service}; + +struct Service {} +#[derive(Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub enum JsMessage { + #[serde(rename = "ipc")] + IPC(IPCMessage), + Attach(i32), + Detach(i32), + Close(i32), + ProcessDead(u32, i32), + CmdDead(i32), + Replspace(i32, ReplspaceMessage), // session, message + Shutdown(bool), // Shutdown the service, value has to be true so that runtime.js can match it in an if check +} -mod parse_paseto; -use parse_paseto::ClientInfo; +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub enum ReplspaceMessage { + GithubTokenReq(String), // nonce + OpenFileReq(String, bool, String), // file, wait for close, nonce + OpenMultipleFiles(Vec, String), // files, nonce -#[cfg(debug_assertions)] -mod services_debug; -#[cfg(debug_assertions)] -use services_debug as services; + GithubTokenRes(String), // token + OpenFileRes, +} -#[cfg(not(debug_assertions))] -mod services_release; -#[cfg(not(debug_assertions))] -use services_release as services; +mod parse_paseto; +use parse_paseto::ClientInfo; mod config; use config::dotreplit::DotReplit; @@ -39,32 +56,33 @@ use lazy_static::lazy_static; lazy_static! { pub static ref START_TIME: Instant = Instant::now(); pub static ref IMPLEMENTED_SERVICES: Vec = { - let mut services = vec![]; - for file in services::get_all().expect("Error when looping over `services/`") { - if let Some(extension) = file.extension() { - if extension == "js" { - let mut service_path = file - .file_name() - .expect("File name missing while extension exists???") - .to_str() - .expect("failed to convert path OsString to String") - .to_string(); - - service_path - .pop() - .expect("Impossible case when removing .js extension from service file"); - service_path - .pop() - .expect("Impossible case when removing .js extension from service file"); - service_path - .pop() - .expect("Impossible case when removing .js extension from service file"); - - services.push(service_path); - } - } - } - services + // let mut services = vec![]; + // for file in services::get_all().expect("Error when looping over `services/`") { + // if let Some(extension) = file.extension() { + // if extension == "js" { + // let mut service_path = file + // .file_name() + // .expect("File name missing while extension exists???") + // .to_str() + // .expect("failed to convert path OsString to String") + // .to_string(); + + // service_path + // .pop() + // .expect("Impossible case when removing .js extension from service file"); + // service_path + // .pop() + // .expect("Impossible case when removing .js extension from service file"); + // service_path + // .pop() + // .expect("Impossible case when removing .js extension from service file"); + + // services.push(service_path); + // } + // } + // } + // services + vec![] }; pub static ref DOTREPLIT_CONFIG: DotReplit = toml::from_str(&std::fs::read_to_string(".replit").unwrap_or("".to_string())).unwrap(); @@ -107,28 +125,28 @@ mod database; #[cfg(feature = "database")] pub use database::DATABASE; -mod goval_server; +// mod goval_server; #[tokio::main] async fn main() -> Result<(), Error> { debug!("Initializing lazy statics"); lazy_static::initialize(&START_TIME); - lazy_static::initialize(&IMPLEMENTED_SERVICES); - lazy_static::initialize(&DOTREPLIT_CONFIG); - lazy_static::initialize(&MAX_SESSION); - lazy_static::initialize(&MAX_CHANNEL); - lazy_static::initialize(&SESSION_CHANNELS); - lazy_static::initialize(&SESSION_CLIENT_INFO); - lazy_static::initialize(&CHANNEL_MESSAGES); - lazy_static::initialize(&CHANNEL_METADATA); - // lazy_static::initialize(&CHANNEL_SESSIONS); - lazy_static::initialize(&SESSION_MAP); - lazy_static::initialize(&PROCCESS_WRITE_MESSAGES); - lazy_static::initialize(&PROCCESS_CHANNEL_TO_ID); - lazy_static::initialize(&CPU_STATS); - lazy_static::initialize(&LAST_SESSION_USING_CHANNEL); - lazy_static::initialize(&REPLSPACE_CALLBACKS); - lazy_static::initialize(&CHILD_PROCS_ENV_BASE); + // lazy_static::initialize(&IMPLEMENTED_SERVICES); + // lazy_static::initialize(&DOTREPLIT_CONFIG); + // lazy_static::initialize(&MAX_SESSION); + // lazy_static::initialize(&MAX_CHANNEL); + // lazy_static::initialize(&SESSION_CHANNELS); + // lazy_static::initialize(&SESSION_CLIENT_INFO); + // lazy_static::initialize(&CHANNEL_MESSAGES); + // lazy_static::initialize(&CHANNEL_METADATA); + // // lazy_static::initialize(&CHANNEL_SESSIONS); + // lazy_static::initialize(&SESSION_MAP); + // lazy_static::initialize(&PROCCESS_WRITE_MESSAGES); + // lazy_static::initialize(&PROCCESS_CHANNEL_TO_ID); + // lazy_static::initialize(&CPU_STATS); + // lazy_static::initialize(&LAST_SESSION_USING_CHANNEL); + // lazy_static::initialize(&REPLSPACE_CALLBACKS); + // lazy_static::initialize(&CHILD_PROCS_ENV_BASE); debug!("Lazy statics initialized successfully"); // console_subscriber::init(); @@ -145,7 +163,7 @@ async fn main() -> Result<(), Error> { #[cfg(feature = "repldb")] tokio::spawn(repldb_server::start_server()); - goval_server::start_server().await.unwrap(); + // goval_server::start_server().await.unwrap(); Ok(()) } diff --git a/src/parse_paseto.rs b/src/parse_paseto.rs index 0a38b85..b1c7a0f 100644 --- a/src/parse_paseto.rs +++ b/src/parse_paseto.rs @@ -1,5 +1,5 @@ +use anyhow::Result; use base64::{engine::general_purpose, Engine as _}; -use deno_core::error::AnyError; use homeval::goval; use prost::Message; use serde::{Deserialize, Serialize}; @@ -37,20 +37,14 @@ impl ClientInfo { } } -fn parse_noverify(token: &str) -> Result<(Vec, bool), AnyError> { +fn parse_noverify(token: &str) -> Result<(Vec, bool)> { let token_parts = token.split(".").collect::>(); if token_parts.len() < 3 { - return Err(AnyError::new(Error::new( - std::io::ErrorKind::InvalidData, - "Invalid Token", - ))); + return Err(Error::new(std::io::ErrorKind::InvalidData, "Invalid Token").into()); } if token_parts[0] != "v2" || token_parts[1] != "public" { - return Err(AnyError::new(std::io::Error::new( - std::io::ErrorKind::InvalidData, - "Invalid Token", - ))); + return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid Token").into()); } let decoded = general_purpose::URL_SAFE_NO_PAD.decode(token_parts[2].as_bytes())?; @@ -61,7 +55,7 @@ fn parse_noverify(token: &str) -> Result<(Vec, bool), AnyError> { } #[cfg(feature = "verify_connections")] -async fn init_keys() -> Result, AnyError> { +async fn init_keys() -> Result> { let key_get = std::env::var("HOMEVAL_PASETO_KEY_URL")?; let https = hyper_tls::HttpsConnector::new(); @@ -74,7 +68,7 @@ async fn init_keys() -> Result, AnyErr } #[cfg(feature = "verify_connections")] -async fn parse_verify(input: &str) -> Result<(Vec, bool), AnyError> { +async fn parse_verify(input: &str) -> Result<(Vec, bool)> { let keys = KEYS.get_or_try_init(init_keys).await?; let token: pasetors::token::UntrustedToken; @@ -141,7 +135,7 @@ async fn parse_verify(input: &str) -> Result<(Vec, bool), AnyError> { Ok((result.payload().as_bytes().to_vec(), true)) } -pub async fn parse(token: &str) -> Result { +pub async fn parse(token: &str) -> Result { let msg; let is_secure; diff --git a/src/repldb_server.rs b/src/repldb_server.rs index ceb9c48..d5475de 100644 --- a/src/repldb_server.rs +++ b/src/repldb_server.rs @@ -1,10 +1,10 @@ +use anyhow::Result; use axum::{ extract::{Path, Query}, http::StatusCode, routing::{delete, get, post}, Form, Router, }; -use deno_core::error::AnyError; use entity::repldb; use log::{as_error, error, info, warn}; use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; @@ -12,7 +12,7 @@ use sea_query::OnConflict; use serde::Deserialize; use std::{collections::HashMap, net::TcpListener}; -pub async fn start_server() -> Result<(), AnyError> { +pub async fn start_server() -> Result<()> { if let None = crate::DATABASE.get() { warn!("Database missing, disabling repldb server."); return Ok(()); diff --git a/src/replspace_server.rs b/src/replspace_server.rs index 5c496c8..d75856a 100644 --- a/src/replspace_server.rs +++ b/src/replspace_server.rs @@ -1,18 +1,18 @@ +use anyhow::Result; use axum::{ extract::Query, http::StatusCode, routing::{get, post}, Json, Router, }; -use deno_core::error::AnyError; use log::{as_debug, as_error, debug, error, info}; use serde::{Deserialize, Serialize}; use textnonce::TextNonce; use tokio::sync::oneshot::channel; -use crate::deno_extension::{messaging::ReplspaceMessage, JsMessage}; +use crate::{JsMessage, ReplspaceMessage}; -pub async fn start_server() -> Result<(), AnyError> { +pub async fn start_server() -> Result<()> { info!("Replspace api server listening on: 127.0.0.1:8283"); let app = Router::new() .route("/files/open", post(open_file)) diff --git a/src/runtime.js b/src/runtime.js deleted file mode 100644 index 47439f6..0000000 --- a/src/runtime.js +++ /dev/null @@ -1,480 +0,0 @@ -// @ts-nocheck -// rome-ignore lint/suspicious/noShadowRestrictedNames: -((globalThis) => { - const core = Deno.core; - - function argsToMessage(...args) { - return args.map((arg) => JSON.stringify(arg !== undefined ? arg : null)) - .join(" "); - } - - function makeLog(level) { - return (...args) => { - Deno.core.ops.op_console_log( - level, - serviceInfo, - `${argsToMessage(...args)}`, - ); - }; - } - - globalThis.console = { - debug: makeLog("debug"), - log: makeLog("info"), - info: makeLog("info"), - warn: makeLog("warn"), - error: makeLog("error"), - trace: makeLog("trace"), - }; -})(globalThis); - -globalThis.fs = { - async stat(path) { - try { - return await Deno.core.ops.op_stat_file(path) - } catch(err) { - // file doesnt exist - return { exists: false } - } - }, - async readDir(path) { - return await Deno.core.ops.op_list_dir(path); - }, - async makeDir(path) { - return await Deno.core.ops.op_make_dir(path) - }, - async writeFile(path, contents = []) { - return await Deno.core.ops.op_write_file(path, contents); - }, - async writeFileString(path, contents = "") { - return await Deno.core.ops.op_write_file_string(path, contents); - }, - async readFile(path) { - return await Deno.core.ops.op_read_file(path); - }, - async readFileString(path) { - return await Deno.core.ops.op_read_file_string(path); - }, - async remove(path) { - return await Deno.core.ops.op_remove_file(path); - }, - async rename(oldPath, newPath) { - return await Deno.core.ops.op_move_file(oldPath, newPath); - }, -}; - -globalThis.Date = { - now: () => { - return BigInt(Deno.core.ops.op_time_milliseconds()); - }, -}; - -class ServiceBase { - constructor(id, service, name) { - this.id = id; - this.service = service; - this.name = name; - this.clients = []; - - this._online = true; - } - - async stop() { - await this.shutdown() - this._online = false - } - - async start() { - while (this._online) { - await this.ipc_recv(); - } - } - - async ipc_recv() { - const message = await Deno.core.ops.op_recv_info(this.id); - - if (message.attach) { - await this._attach(message.attach); - } else if (message.ipc) { - await this._recv(message); - } else if (message.close) { - await this._detach(message.close, true); - } else if (message.detach) { - await this._detach(message.close, false); - } else if (message.processDead) { - await this.process_dead(message.processDead[0], message.processDead[1]) - } else if (message.cmdDead != null) { - await this.process_dead(-1, message.cmdDead) - } else if (message.replspace) { - await this.on_replspace(message.replspace[0], message.replspace[1]) - } else if (message.shutdown) { - await this.stop() - await Deno.core.ops.op_ack_shutdown(this.id) - } else { - console.error("Unknown IPC message", message); - } - } - - async shutdown() {} - - async process_dead(proc_id, exit_code) { - console.warn(`PTY/CMD ${proc_id} died with status ${exit_code} and channel ${this.id} doesn't have a listener`) - } - - async _recv(message) { - const cmd = api.Command.decode(message.ipc.bytes); - - let res = null; - - try { - res = await this.recv(cmd, message.ipc.session); - } catch (err) { - res = api.Command.create({ error: err.toString(), ref: cmd.ref }); - console.error(err.toString() + err.stack ? `\n${err.stack}` : ""); - } - - if (res) { - res.ref = cmd.ref; - await this.send(res, message.ipc.session); - } - } - - async recv(_c, _s) { - throw new Error("Not implemented"); - } - - async _send(cmd, session) { - const buf = [...Buffer.from(api.Command.encode(cmd).finish())]; - await Deno.core.ops.op_send_msg({ - bytes: buf, - session: session, - }); - } - - async send(cmd, session) { - cmd.channel = this.id; - cmd.session = session; - - if (session > 0) { - await this._send(cmd, session); - } else if (session === 0) { - for (let client of this.clients) { - await this._send(cmd, client); - } - } else if (session < 0) { - const ignore = Math.abs(session); - for (let client of this.clients) { - if (client === ignore) { - continue; - } - await this._send(cmd, client); - } - } - } - - async _attach(session) { - this.clients.push(session); - await this.attach(session); - } - - async attach(_) { - } - - async _detach(session, forced) { - this.clients = this.clients.filter((item) => item !== session); - await this.detach(session, forced); - } - - async detach(_session, _forced) {} - - async on_replspace(_session, _msg) {} - - async replspace_reply(nonce, message) { - await Deno.core.ops.op_replspace_reply(nonce, message); - } -} - -class PtyProcess { - constructor(channel, command, args = [], env_vars = {}) { - this.env_vars = env_vars; - this.channel = channel; - this.command = command; - this.args = args; - this.id = null; - } - - async init(sessions = []) { - this.id = await Deno.core.ops.op_register_pty([this.command, ...this.args], this.channel, sessions, this.env_vars); - } - - async destroy() { - await Deno.core.ops.op_destroy_pty(this.id, this.channel); - } - - async add_session(session) { - await this._await_pty_exists(); - await Deno.core.ops.op_pty_add_session(this.id, session); - } - - async remove_session(session) { - await this._await_pty_exists(); - await Deno.core.ops.op_pty_remove_session(this.id, session); - } - - async write(input) { - await this._await_pty_exists(); - await Deno.core.ops.op_pty_write_msg(this.id, input); - } - - // ensure pty exists, if not wait in a non-blocking manner - // used by functions that queue inputs instead of erroring - // when the pty isn't initialized yet - async _await_pty_exists() { - // fast path - if (this.id != null) return; - - let loops = 0; - let warned = false; - - while (true) { - if (this.id != null) break; - - await Deno.core.ops.op_sleep(1); - loops += 1; - - if (loops > 1000 && !warned) { - warned = true - console.warn( - "Pty has waited for more than 1 second to initialize, please check this out", - ); - } - } - } -} - -class Process { - constructor(channel, command, args = [], env_vars = {}) { - this.env_vars = env_vars; - this.channel = channel; - this.command = command; - this.args = args; - this.id = null; - } - - async init(sessions = []) { - this.id = await Deno.core.ops.op_register_cmd([this.command, ...this.args], this.channel, sessions, this.env_vars); - } - - async destroy() { - await Deno.core.ops.op_destroy_cmd(this.id, this.channel); - } - - async add_session(session) { - await this._await_cmd_exists(); - await Deno.core.ops.op_cmd_add_session(this.id, session); - } - - async remove_session(session) { - await this._await_cmd_exists(); - await Deno.core.ops.op_cmd_remove_session(this.id, session); - } - - async write(input) { - await this._await_cmd_exists(); - await Deno.core.ops.op_cmd_write_msg(this.id, input); - } - - // ensure cmd exists, if not wait in a non-blocking manner - // used by functions that queue inputs instead of erroring - // when the cmd isn't initialized yet - async _await_cmd_exists() { - // fast path - if (this.id != null) return; - - let loops = 0; - let warned = false; - - while (true) { - if (this.id != null) break; - - await Deno.core.ops.op_sleep(1); - loops += 1; - - if (loops > 1000 && !warned) { - warned = true - console.warn( - "Cmd has waited for more than 1 second to initialize, please check this out", - ); - } - } - } -} - -class FileWatcher { - constructor() { - this.listeners = [] - this.watched_files = 0 - - this.online = true - } - - async init() { - this.id = await Deno.core.ops.op_make_filewatcher(); - } - - async watch(paths) { - this.watched_files += paths.length - await this._await_watcher_exists() - await Deno.core.ops.op_watch_files(this.id, paths) - } - - add_listener(listener) { - this.listeners.push(listener) - } - - async stop() { - await Deno.core.ops.op_shutdown_filewatcher(this.id) - this.online = false; - } - - async start() { - await this._await_watcher_exists() - let attempts = 0; - while (this.online) { - const msg = await Deno.core.ops.op_recv_fsevent(this.id) - if (msg.shutdown) { - this.online = false - break - } - if (msg.err) { - if (attempts === 3) { - throw new Error("FileWatcher has had 3 consecutive errors") - } - - console.warn("Got error in FileWatcher, retrying:", msg.err) - attempts += 1; - await Deno.core.ops.op_sleep(100); - continue - } - - for (let listener of this.listeners) { - listener(msg) - } - attempts = 0; - } - } - - async _await_watcher_exists() { - // fast path - if (this.id != null) return; - - let loops = 0; - let warned = false; - - while (true) { - if (this.id != null) break; - - await Deno.core.ops.op_sleep(1); - loops += 1; - - if (loops > 1000 && !warned) { - warned = true - console.warn( - "File watcher has waited for more than 1 second to initialize, please check this out", - ); - } - } - } -} - -globalThis.process = { - env: new Proxy({}, { - get(_target, prop, _recveiver) { - return Deno.core.ops.op_get_env_var(prop) - }, - set() { - throw new Error("Setting env vars is currently unimplemented"); - }, - }), - system: { - async cpuTime() { - return await Deno.core.ops.op_cpu_info() - }, - async memoryUsage() { - return await Deno.core.ops.op_memory_info() - }, - async diskUsage() { - return await Deno.core.ops.op_disk_info(); - }, - get os() { - return Deno.core.ops.op_get_running_os(); - } - }, - database: { - _supported: null, - get supported() { - if (process.database._supported != null) { - return process.database._supported - } - - let support = Deno.core.ops.op_database_exists(); - process.database._supported = support; - return support; - }, - async getFile(name) { - if (!process.database.supported) { - throw new Error("No database support :/") - } - - return await Deno.core.ops.op_database_get_file(name) - }, - async setFile(file_model) { - if (!process.database.supported) { - throw new Error("No database support :/") - } - - return await Deno.core.ops.op_database_set_file(file_model) - } - }, - server: { - name() { - return Deno.core.ops.op_server_name() - }, - version() { - return Deno.core.ops.op_server_version() - }, - license() { - return Deno.core.ops.op_server_license() - }, - repository() { - return Deno.core.ops.op_server_repository() - }, - description() { - return Deno.core.ops.op_server_description() - }, - uptime() { - return Deno.core.ops.op_server_uptime() - }, - services() { - return Deno.core.ops.op_get_supported_services() - }, - authors() { - const authors = Deno.core.ops.op_server_authors(); - return authors.split(":") - } - }, - async getUserInfo(session) { - return await Deno.core.ops.op_user_info(session) - }, - getDotreplitConfig() { - return Deno.core.ops.op_get_dotreplit_config() - }, - - async quickCommand(args, channel, sessions, env = {}) { - return await Deno.core.ops.op_run_cmd(args, channel, sessions, env) - } -}; - -globalThis.diffText = async (old_text, new_text) => { - return await Deno.core.ops.op_diff_texts(old_text, new_text) -} \ No newline at end of file diff --git a/src/services_debug.rs b/src/services_debug.rs deleted file mode 100644 index 77d08cd..0000000 --- a/src/services_debug.rs +++ /dev/null @@ -1,16 +0,0 @@ -use std::io::Error; -use std::path::PathBuf; - -#[inline(always)] -pub fn get_module_core(_: String) -> Result, Error> { - Ok(None) -} - -#[inline(always)] -pub fn get_all() -> Result, Error> { - let mut res = vec![]; - for file in std::fs::read_dir("services/").expect("Error reading services") { - res.push(file.unwrap().path()) - } - Ok(res) -} diff --git a/src/services_release.rs b/src/services_release.rs deleted file mode 100644 index e470067..0000000 --- a/src/services_release.rs +++ /dev/null @@ -1,33 +0,0 @@ -use std::{io::Error, path::PathBuf}; - -use include_directory::{include_directory, Dir}; -static SERVICES_DIR: Dir<'_> = include_directory!("$CARGO_MANIFEST_DIR/services"); - -#[inline(always)] -pub fn get_module_core(service: String) -> Result, Error> { - match SERVICES_DIR.get_file(format!("{}.js", service)) { - Some(file) => { - return match file.contents_utf8() { - Some(contents) => Ok(Some(deno_core::FastString::Static(contents))), - None => Err(Error::new( - std::io::ErrorKind::InvalidData, - format!("Module: {} has None for .contents_utf8()", service), - )), - } - } - None => Err(Error::new( - std::io::ErrorKind::NotFound, - format!("Module: {} has None for .contents_utf8()", service), - )), - } -} - -// TODO: compute this at compile time -#[inline(always)] -pub fn get_all() -> Result, Error> { - let mut res = vec![]; - for file in SERVICES_DIR.files() { - res.push(file.path().to_path_buf()) - } - Ok(res) -} diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 2ed032c..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "compilerOptions": { - "lib": [ - "ESNext" - ], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "strict": true, - "downlevelIteration": true, - // "skipLibCheck": true, - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "typeRoots": ["types"], - }, - "exclude": [ - "target", - "node_modules", - "src/runtime.js" - ] -} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index f5e64cb..0000000 --- a/yarn.lock +++ /dev/null @@ -1,149 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 -# bun ./bun.lockb --hash: 6A18D2FE0E7EC660-897e51ca14ee6952-29F21B2368B8158D-c53130ed4e9c2061 - - -"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz" - integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== - -"@protobufjs/base64@^1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz" - integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== - -"@protobufjs/codegen@^2.0.4": - version "2.0.4" - resolved "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz" - integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== - -"@protobufjs/eventemitter@^1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz" - integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== - -"@protobufjs/fetch@^1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz" - integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== - dependencies: - "@protobufjs/aspromise" "^1.1.1" - "@protobufjs/inquire" "^1.1.0" - -"@protobufjs/float@^1.0.2": - version "1.0.2" - resolved "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz" - integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== - -"@protobufjs/inquire@^1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz" - integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== - -"@protobufjs/path@^1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz" - integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== - -"@protobufjs/pool@^1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz" - integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== - -"@protobufjs/utf8@^1.1.0": - version "1.1.0" - resolved "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz" - integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== - -"@replit/protocol@^0.3.12": - version "0.3.12" - resolved "https://registry.npmjs.org/@replit/protocol/-/protocol-0.3.12.tgz" - integrity sha512-clVyvp5qjteTOwJ3dCadFDR3bu15tlBl+OcbskoAMgVk2Ye1bqMce4O14bO/zBSpavheRlxVgt5d+sZ2HcbCSg== - dependencies: - protobufjs "^6.11.3" - -"@types/long@^4.0.1": - version "4.0.2" - resolved "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz" - integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== - -"@types/node@>=13.7.0": - version "20.1.1" - resolved "https://registry.npmjs.org/@types/node/-/node-20.1.1.tgz" - integrity sha512-uKBEevTNb+l6/aCQaKVnUModfEMjAl98lw2Si9P5y4hLu9tm6AlX2ZIoXZX6Wh9lJueYPrGPKk5WMCNHg/u6/A== - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -crc-32@^1.2.2: - version "1.2.2" - resolved "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz" - integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== - -fastestsmallesttextencoderdecoder@^1.0.22: - version "1.0.22" - resolved "https://registry.npmjs.org/fastestsmallesttextencoderdecoder/-/fastestsmallesttextencoderdecoder-1.0.22.tgz" - integrity sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw== - -ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -long@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/long/-/long-4.0.0.tgz" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== - -long@^5.0.0: - version "5.2.3" - resolved "https://registry.npmjs.org/long/-/long-5.2.3.tgz" - integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== - -protobufjs@^6.11.3: - version "6.11.3" - resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz" - integrity sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/long" "^4.0.1" - "@types/node" ">=13.7.0" - long "^4.0.0" - -protobufjs@^7.2.3: - version "7.2.3" - resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.3.tgz" - integrity sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/node" ">=13.7.0" - long "^5.0.0" From e66729b3c393c24cb02d6ba74b6e1a3a18a60d97 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Wed, 21 Jun 2023 16:11:22 -0700 Subject: [PATCH 002/103] Merge branch 'remove-lazy-static' --- Cargo.lock | 1 - Cargo.toml | 1 - rust-toolchain.toml | 2 + src/deno_extension/cmd.rs | 17 ++-- src/deno_extension/fs_events.rs | 23 +++--- src/deno_extension/pty.rs | 17 ++-- src/goval_server.rs | 6 +- src/main.rs | 136 ++++++++++++-------------------- 8 files changed, 80 insertions(+), 123 deletions(-) create mode 100644 rust-toolchain.toml diff --git a/Cargo.lock b/Cargo.lock index 29733fc..e5ebce9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1011,7 +1011,6 @@ dependencies = [ "hyper", "hyper-tls", "include_directory", - "lazy_static", "log", "migration", "notify-debouncer-full", diff --git a/Cargo.toml b/Cargo.toml index b4f9b1a..cdce4f9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,6 @@ verify_connections = ["dep:pasetors", "dep:hyper", "dep:hyper-tls"] env_logger = { git = "https://github.com/tmccombs/env_logger", rev = "a47d1d99", features=["kv_unstable"] } futures-channel = "0.3.26" futures-util = "0.3.26" -lazy_static = "1.4.0" log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } prost = "0.11.8" prost-types = "0.11.8" diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..5d56faf --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/src/deno_extension/cmd.rs b/src/deno_extension/cmd.rs index 22fb424..f36301c 100644 --- a/src/deno_extension/cmd.rs +++ b/src/deno_extension/cmd.rs @@ -5,7 +5,7 @@ use std::{ io::{Error, ErrorKind}, pin::Pin, process::Stdio, - sync::Arc, + sync::{Arc, LazyLock}, task::{Context, Poll}, }; @@ -19,19 +19,12 @@ use tokio::{ use deno_core::{error::AnyError, op, OpDecl}; -use lazy_static::lazy_static; - use crate::JsMessage; -lazy_static! { - static ref MAX_SESSION: Arc> = Arc::new(Mutex::new(0)); -} - -lazy_static! { - static ref CMD_CANCELLATION_MAP: RwLock> = - RwLock::new(HashMap::new()); - static ref CMD_SESSION_MAP: RwLock>> = RwLock::new(HashMap::new()); -} +static CMD_CANCELLATION_MAP: LazyLock>> = + LazyLock::new(|| RwLock::new(HashMap::new())); +static CMD_SESSION_MAP: LazyLock>>> = + LazyLock::new(|| RwLock::new(HashMap::new())); struct CmdWriter { channel: i32, diff --git a/src/deno_extension/fs_events.rs b/src/deno_extension/fs_events.rs index dd3d699..a244fe2 100644 --- a/src/deno_extension/fs_events.rs +++ b/src/deno_extension/fs_events.rs @@ -9,17 +9,22 @@ use serde::Serialize; use deno_core::error::AnyError; -use lazy_static::lazy_static; -use std::{collections::HashMap, io::Error, path::Path, sync::Arc, time::Duration}; +use std::{ + collections::HashMap, + io::Error, + path::Path, + sync::{Arc, LazyLock}, + time::Duration, +}; use tokio::sync::{Mutex, RwLock}; -lazy_static! { - static ref FILE_WATCHER_MAP: Arc>>>>> = - Arc::new(RwLock::new(HashMap::new())); - static ref FILE_WATCHER_MESSAGES: Arc>>>> = - Arc::new(RwLock::new(HashMap::new())); - static ref MAX_WATCHER: Arc> = Arc::new(Mutex::new(0)); -} +static FILE_WATCHER_MAP: LazyLock< + RwLock>>>>, +> = LazyLock::new(|| RwLock::new(HashMap::new())); +static FILE_WATCHER_MESSAGES: LazyLock< + RwLock>>>, +> = LazyLock::new(|| RwLock::new(HashMap::new())); +static MAX_WATCHER: LazyLock> = LazyLock::new(|| Mutex::new(0)); #[derive(Serialize)] #[serde(rename_all = "camelCase")] diff --git a/src/deno_extension/pty.rs b/src/deno_extension/pty.rs index 4ac7c17..33b107f 100644 --- a/src/deno_extension/pty.rs +++ b/src/deno_extension/pty.rs @@ -4,7 +4,7 @@ use portable_pty::PtySize; use std::{ collections::{HashMap, VecDeque}, io::{Error, ErrorKind, Write}, - sync::Arc, + sync::{Arc, LazyLock}, }; use crate::channels::IPCMessage; @@ -13,19 +13,12 @@ use tokio::sync::{Mutex, RwLock}; use deno_core::{error::AnyError, op, OpDecl}; -use lazy_static::lazy_static; - use crate::JsMessage; -lazy_static! { - static ref MAX_SESSION: Arc> = Arc::new(Mutex::new(0)); -} - -lazy_static! { - static ref PTY_CANCELLATION_MAP: RwLock> = - RwLock::new(HashMap::new()); - static ref PTY_SESSION_MAP: RwLock>> = RwLock::new(HashMap::new()); -} +static PTY_CANCELLATION_MAP: LazyLock>> = + LazyLock::new(|| RwLock::new(HashMap::new())); +static PTY_SESSION_MAP: LazyLock>>> = + LazyLock::new(|| RwLock::new(HashMap::new())); struct PtyWriter { channel: i32, diff --git a/src/goval_server.rs b/src/goval_server.rs index 4cd886e..93a340d 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -23,7 +23,7 @@ use homeval::goval; use homeval::goval::Command; use prost::Message; use tokio::sync::mpsc::UnboundedSender; -use std::net::SocketAddr; +use std::{net::SocketAddr, sync::LazyLock}; use std::sync::Arc; use futures_util::{SinkExt, StreamExt}; @@ -85,7 +85,7 @@ pub async fn start_server() -> Result<(), AnyError> { }); while let Some(message) = rx.recv().await { - handle_message(message, SESSION_MAP.clone()).await; + handle_message(message, &SESSION_MAP).await; } Ok(()) @@ -136,7 +136,7 @@ async fn wsv2( ws.on_upgrade(move |socket| on_wsv2_upgrade(socket, token, state, addr)) } -async fn handle_message(message: IPCMessage, session_map: Arc>>>) { +async fn handle_message(message: IPCMessage, session_map: &LazyLock>>>) { let cmd: Command; match message.to_cmd() { Err(err) => { diff --git a/src/main.rs b/src/main.rs index aa54227..699cdaa 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,10 @@ -// use deno_extension::messaging::ReplspaceMessage; +#![feature(lazy_cell)] + +use deno_extension::messaging::ReplspaceMessage; use homeval::goval; use serde::{Deserialize, Serialize}; +use std::sync::LazyLock; use std::time::Instant; use std::{collections::HashMap, io::Error, sync::Arc}; @@ -52,73 +55,50 @@ mod replspace_server; #[cfg(feature = "repldb")] mod repldb_server; -use lazy_static::lazy_static; -lazy_static! { - pub static ref START_TIME: Instant = Instant::now(); - pub static ref IMPLEMENTED_SERVICES: Vec = { - // let mut services = vec![]; - // for file in services::get_all().expect("Error when looping over `services/`") { - // if let Some(extension) = file.extension() { - // if extension == "js" { - // let mut service_path = file - // .file_name() - // .expect("File name missing while extension exists???") - // .to_str() - // .expect("failed to convert path OsString to String") - // .to_string(); - - // service_path - // .pop() - // .expect("Impossible case when removing .js extension from service file"); - // service_path - // .pop() - // .expect("Impossible case when removing .js extension from service file"); - // service_path - // .pop() - // .expect("Impossible case when removing .js extension from service file"); - - // services.push(service_path); - // } - // } - // } - // services - vec![] - }; - pub static ref DOTREPLIT_CONFIG: DotReplit = - toml::from_str(&std::fs::read_to_string(".replit").unwrap_or("".to_string())).unwrap(); -} - -lazy_static! { - static ref MAX_SESSION: Arc> = Arc::new(Mutex::new(0)); - static ref MAX_CHANNEL: Arc> = Arc::new(Mutex::new(0)); -} - -lazy_static! { - static ref SESSION_CHANNELS: RwLock>> = RwLock::new(HashMap::new()); - static ref SESSION_CLIENT_INFO: RwLock> = RwLock::new(HashMap::new()); - static ref CHANNEL_MESSAGES: Arc>>>> = - Arc::new(RwLock::new(HashMap::new())); - static ref CHANNEL_METADATA: RwLock> = RwLock::new(HashMap::new()); - static ref CHANNEL_SESSIONS: RwLock>> = RwLock::new(HashMap::new()); - - static ref SESSION_MAP: Arc>>> = - Arc::new(RwLock::new(HashMap::new())); - - // pty and cmd's - static ref PROCCESS_WRITE_MESSAGES: RwLock>>> = - RwLock::new(HashMap::new()); - static ref PROCCESS_CHANNEL_TO_ID: RwLock> = RwLock::new(HashMap::new()); - - static ref CPU_STATS: Arc = Arc::new(cpu_time::ProcessTime::now()); - - // Hashmap for channel id -> last session that sent it a message - static ref LAST_SESSION_USING_CHANNEL: Arc>> = Arc::new(RwLock::new(HashMap::new())); - - static ref REPLSPACE_CALLBACKS: Arc>>>> = - Arc::new(RwLock::new(HashMap::new())); - - static ref CHILD_PROCS_ENV_BASE: Arc>> = Arc::new(RwLock::new(HashMap::new())); -} +pub static START_TIME: LazyLock = LazyLock::new(Instant::now); +static CPU_STATS: LazyLock> = + LazyLock::new(|| Arc::new(cpu_time::ProcessTime::now())); + +pub static IMPLEMENTED_SERVICES: LazyLock> = LazyLock::new(|| vec![]); + +pub static DOTREPLIT_CONFIG: LazyLock = LazyLock::new(|| { + toml::from_str(&std::fs::read_to_string(".replit").unwrap_or("".to_string())).unwrap() +}); + +static MAX_SESSION: LazyLock> = LazyLock::new(|| Mutex::new(0)); +static MAX_CHANNEL: LazyLock> = LazyLock::new(|| Mutex::new(0)); + +static SESSION_CHANNELS: LazyLock>>> = + LazyLock::new(|| RwLock::new(HashMap::new())); +static SESSION_CLIENT_INFO: LazyLock>> = + LazyLock::new(|| RwLock::new(HashMap::new())); +static CHANNEL_MESSAGES: LazyLock< + RwLock>>>, +> = LazyLock::new(|| RwLock::new(HashMap::new())); +static CHANNEL_METADATA: LazyLock>> = + LazyLock::new(|| RwLock::new(HashMap::new())); +static CHANNEL_SESSIONS: LazyLock>>> = + LazyLock::new(|| RwLock::new(HashMap::new())); +static SESSION_MAP: LazyLock>>> = + LazyLock::new(|| RwLock::new(HashMap::new())); + +// pty and cmd's +static PROCCESS_WRITE_MESSAGES: LazyLock< + RwLock>>>, +> = LazyLock::new(|| RwLock::new(HashMap::new())); +static PROCCESS_CHANNEL_TO_ID: LazyLock>> = + LazyLock::new(|| RwLock::new(HashMap::new())); + +// Hashmap for channel id -> last session that sent it a message +static LAST_SESSION_USING_CHANNEL: LazyLock>> = + LazyLock::new(|| RwLock::new(HashMap::new())); + +static REPLSPACE_CALLBACKS: LazyLock< + RwLock>>>, +> = LazyLock::new(|| RwLock::new(HashMap::new())); + +static CHILD_PROCS_ENV_BASE: LazyLock>> = + LazyLock::new(|| RwLock::new(HashMap::new())); #[cfg(feature = "database")] mod database; @@ -130,23 +110,9 @@ pub use database::DATABASE; #[tokio::main] async fn main() -> Result<(), Error> { debug!("Initializing lazy statics"); - lazy_static::initialize(&START_TIME); - // lazy_static::initialize(&IMPLEMENTED_SERVICES); - // lazy_static::initialize(&DOTREPLIT_CONFIG); - // lazy_static::initialize(&MAX_SESSION); - // lazy_static::initialize(&MAX_CHANNEL); - // lazy_static::initialize(&SESSION_CHANNELS); - // lazy_static::initialize(&SESSION_CLIENT_INFO); - // lazy_static::initialize(&CHANNEL_MESSAGES); - // lazy_static::initialize(&CHANNEL_METADATA); - // // lazy_static::initialize(&CHANNEL_SESSIONS); - // lazy_static::initialize(&SESSION_MAP); - // lazy_static::initialize(&PROCCESS_WRITE_MESSAGES); - // lazy_static::initialize(&PROCCESS_CHANNEL_TO_ID); - // lazy_static::initialize(&CPU_STATS); - // lazy_static::initialize(&LAST_SESSION_USING_CHANNEL); - // lazy_static::initialize(&REPLSPACE_CALLBACKS); - // lazy_static::initialize(&CHILD_PROCS_ENV_BASE); + LazyLock::force(&START_TIME); + LazyLock::force(&CPU_STATS); + debug!("Lazy statics initialized successfully"); // console_subscriber::init(); From b1e4e34ed2d6dd8ecc13ca8816bc7ee45f033056 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Wed, 21 Jun 2023 17:23:11 -0700 Subject: [PATCH 003/103] refactor: Start implementing rust based services --- Cargo.lock | 90 +-- Cargo.toml | 11 +- build.rs | 19 - protobuf/Cargo.toml | 13 + protobuf/build.rs | 12 + {src/protobufs => protobuf/src}/goval.proto | 0 protobuf/src/lib.rs | 2 + services/Cargo.toml | 8 + services/src/chat.rs | 8 + services/src/lib.rs | 26 + services/src/main.rs | 3 - services/src/traits.rs | 3 + services/src/types.rs | 61 ++ src/channels.rs | 29 - src/config.rs | 2 +- src/goval_server.rs | 616 ++++++++++---------- src/lib.rs | 4 - src/main.rs | 43 +- src/parse_paseto.rs | 2 +- 19 files changed, 448 insertions(+), 504 deletions(-) delete mode 100644 build.rs create mode 100644 protobuf/Cargo.toml create mode 100644 protobuf/build.rs rename {src/protobufs => protobuf/src}/goval.proto (100%) create mode 100644 protobuf/src/lib.rs create mode 100644 services/src/chat.rs create mode 100644 services/src/lib.rs delete mode 100644 services/src/main.rs create mode 100644 services/src/traits.rs create mode 100644 services/src/types.rs delete mode 100644 src/channels.rs delete mode 100644 src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index e5ebce9..9500eb8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -868,17 +868,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "ghost" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e77ac7b51b8e6313251737fcef4b1c01a2ea102bde68415b62c0ee9268fec357" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.18", -] - [[package]] name = "h2" version = "0.3.19" @@ -1017,13 +1006,13 @@ dependencies = [ "pasetors", "portable-pty", "prost", - "prost-build", "prost-types", - "prost-wkt-types", + "protobuf", "sea-orm", "sea-query", "serde", "serde_json", + "services", "similar", "systemstat", "textnonce", @@ -1201,15 +1190,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "inventory" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0539b5de9241582ce6bd6b0ba7399313560151e58c9aaf8b74b711b1bdce644" -dependencies = [ - "ghost", -] - [[package]] name = "io-lifetimes" version = "1.0.11" @@ -1918,46 +1898,12 @@ dependencies = [ ] [[package]] -name = "prost-wkt" -version = "0.4.2" -source = "git+https://github.com/fdeantoni/prost-wkt/?rev=15bc0a06#15bc0a06758054ade99f02a8255d1fd76ba83e12" -dependencies = [ - "chrono", - "inventory", - "prost", - "serde", - "serde_derive", - "serde_json", - "typetag", -] - -[[package]] -name = "prost-wkt-build" -version = "0.4.2" -source = "git+https://github.com/fdeantoni/prost-wkt/?rev=15bc0a06#15bc0a06758054ade99f02a8255d1fd76ba83e12" -dependencies = [ - "heck 0.4.1", - "prost", - "prost-build", - "prost-types", - "quote", -] - -[[package]] -name = "prost-wkt-types" -version = "0.4.2" -source = "git+https://github.com/fdeantoni/prost-wkt/?rev=15bc0a06#15bc0a06758054ade99f02a8255d1fd76ba83e12" +name = "protobuf" +version = "0.1.0" dependencies = [ - "chrono", "prost", "prost-build", "prost-types", - "prost-wkt", - "prost-wkt-build", - "regex", - "serde", - "serde_derive", - "serde_json", ] [[package]] @@ -2587,6 +2533,10 @@ name = "services" version = "0.1.0" dependencies = [ "anyhow", + "deadqueue", + "prost", + "protobuf", + "serde", ] [[package]] @@ -3245,30 +3195,6 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "typetag" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6898cc6f6a32698cc3e14d5632a14d2b23ed9f7b11e6b8e05ce685990acc22" -dependencies = [ - "erased-serde", - "inventory", - "once_cell", - "serde", - "typetag-impl", -] - -[[package]] -name = "typetag-impl" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c3e1c30cedd24fc597f7d37a721efdbdc2b1acae012c1ef1218f4c7c2c0f3e7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.18", -] - [[package]] name = "unicase" version = "2.6.0" diff --git a/Cargo.toml b/Cargo.toml index cdce4f9..265b026 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ description = """A custom implementation of replits evaluation protocol. See https://govaldocs.pages.dev""" [workspace] -members = [".", "migration", "entity", "services"] +members = [".", "migration", "entity", "services", "protobuf"] [features] default = ["replspace", "database", "repldb", "verify_connections"] @@ -20,7 +20,8 @@ fun-stuff = ["dep:chrono", "dep:chrono-tz"] verify_connections = ["dep:pasetors", "dep:hyper", "dep:hyper-tls"] [dependencies] -# deno_core = "0.191.0" +goval = { path = "protobuf", package = "protobuf" } +homeval_services = { path = "services", package = "services" } env_logger = { git = "https://github.com/tmccombs/env_logger", rev = "a47d1d99", features=["kv_unstable"] } futures-channel = "0.3.26" futures-util = "0.3.26" @@ -42,7 +43,6 @@ cpu-time = "1.0.0" notify-debouncer-full = { version = "0.1.0", default-features = false, features = ["serde"] } deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } similar = "2.2.1" -prost-wkt-types = { git = "https://github.com/fdeantoni/prost-wkt/", rev="15bc0a06"} toml = "0.7.4" textnonce = "1.0.0" @@ -58,7 +58,4 @@ sea-query = { version = "0.28.5", optional = true } pasetors = { version = "0.6.7", default-features = false, features = ["v2"], optional = true } hyper = { version = "0.14.26", features = ["http1", "http2", "client"], optional = true } hyper-tls = { version = "0.5.0", optional = true } -anyhow = "1.0.71" - -[build-dependencies] -prost-build = "0.11.8" +anyhow = "1.0.71" \ No newline at end of file diff --git a/build.rs b/build.rs deleted file mode 100644 index b9d963c..0000000 --- a/build.rs +++ /dev/null @@ -1,19 +0,0 @@ -use prost_build::Config; -extern crate prost_build; - -fn main() { - println!("cargo:rerun-if-changed=src/protobufs"); - - println!("cargo:rerun-if-changed=package.json"); - - // Compile protobufs - let mut config = Config::new(); - // config.type_attribute(".", "#[serde(rename_all = \"camelCase\")]"); - config.type_attribute(".", "#[derive(serde::Serialize,serde::Deserialize)]"); - // config.extern_path(".google.protobuf", "::prost_types"); - config.extern_path(".google.protobuf", "::prost-wkt-types"); - config.compile_well_known_types(); - config - .compile_protos(&["src/protobufs/goval.proto"], &["src/"]) - .unwrap(); -} diff --git a/protobuf/Cargo.toml b/protobuf/Cargo.toml new file mode 100644 index 0000000..d4611c1 --- /dev/null +++ b/protobuf/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "protobuf" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +prost = "0.11.8" +prost-types = "0.11.8" + +[build-dependencies] +prost-build = "0.11.8" diff --git a/protobuf/build.rs b/protobuf/build.rs new file mode 100644 index 0000000..a331467 --- /dev/null +++ b/protobuf/build.rs @@ -0,0 +1,12 @@ +use prost_build::Config; +extern crate prost_build; + +fn main() { + println!("cargo:rerun-if-changed=src/goval.protobufs"); + + // Compile protobufs + let mut config = Config::new(); + config + .compile_protos(&["src/goval.proto"], &["src/"]) + .unwrap(); +} diff --git a/src/protobufs/goval.proto b/protobuf/src/goval.proto similarity index 100% rename from src/protobufs/goval.proto rename to protobuf/src/goval.proto diff --git a/protobuf/src/lib.rs b/protobuf/src/lib.rs new file mode 100644 index 0000000..2a39db9 --- /dev/null +++ b/protobuf/src/lib.rs @@ -0,0 +1,2 @@ +// Include the `goval` module, which is generated from goval.proto. +include!(concat!(env!("OUT_DIR"), "/goval.rs")); diff --git a/services/Cargo.toml b/services/Cargo.toml index 8f77204..0e53ab3 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -7,3 +7,11 @@ edition = "2021" [dependencies] anyhow = "1.0.71" +deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } +goval = { package = "protobuf", path = "../protobuf"} +prost = "0.11.9" +serde = "1.0.164" + +[lib] +name = "services" +path = "src/lib.rs" diff --git a/services/src/chat.rs b/services/src/chat.rs new file mode 100644 index 0000000..f15e736 --- /dev/null +++ b/services/src/chat.rs @@ -0,0 +1,8 @@ +pub struct Chat {} +use super::traits; + +impl traits::Service for Chat { + fn attach(self, session: i32) -> Option { + None + } +} diff --git a/services/src/lib.rs b/services/src/lib.rs new file mode 100644 index 0000000..8460dc4 --- /dev/null +++ b/services/src/lib.rs @@ -0,0 +1,26 @@ +mod chat; +mod traits; +mod types; + +pub use types::*; + +pub struct Channel { + pub clients: Vec, + _inner: Box, +} + +impl Channel { + pub fn new( + _id: i32, + service: String, + name: Option, + read: deadqueue::unlimited::Queue, + ) -> Channel { + Channel { + clients: vec![], + _inner: Box::new(chat::Chat {}), + } + } +} + +pub static IMPLEMENTED_SERVICES: &[&str] = &["chat"]; diff --git a/services/src/main.rs b/services/src/main.rs deleted file mode 100644 index e7a11a9..0000000 --- a/services/src/main.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - println!("Hello, world!"); -} diff --git a/services/src/traits.rs b/services/src/traits.rs new file mode 100644 index 0000000..5f879ae --- /dev/null +++ b/services/src/traits.rs @@ -0,0 +1,3 @@ +pub(crate) trait Service { + fn attach(self, session: i32) -> Option; +} diff --git a/services/src/types.rs b/services/src/types.rs new file mode 100644 index 0000000..a5ae6fc --- /dev/null +++ b/services/src/types.rs @@ -0,0 +1,61 @@ +use goval; +use prost::Message; +use serde; +use serde::{Deserialize, Serialize}; + +#[derive(Clone)] +pub struct ServiceMetadata { + pub service: String, + pub name: Option, + pub id: i32, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub enum ReplspaceMessage { + GithubTokenReq(String), // nonce + OpenFileReq(String, bool, String), // file, wait for close, nonce + OpenMultipleFiles(Vec, String), // files, nonce + + GithubTokenRes(String), // token + OpenFileRes, +} + +#[derive(Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub enum JsMessage { + #[serde(rename = "ipc")] + IPC(IPCMessage), + Attach(i32), + Detach(i32), + Close(i32), + ProcessDead(u32, i32), + CmdDead(i32), + Replspace(i32, ReplspaceMessage), // session, message + Shutdown(bool), // Shutdown the service, value has to be true so that runtime.js can match it in an if check +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct IPCMessage { + pub bytes: Vec, + pub session: i32, +} + +impl IPCMessage { + pub fn from_cmd(cmd: goval::Command, session: i32) -> IPCMessage { + let mut bytes = Vec::new(); + bytes.reserve(cmd.encoded_len()); + cmd.encode(&mut bytes).unwrap(); + + IPCMessage { bytes, session } + } + + pub fn to_cmd(&self) -> Result { + Ok(goval::Command::decode(&*self.bytes)?) + } + + pub fn replace_cmd(&self, cmd: goval::Command) -> IPCMessage { + IPCMessage::from_cmd(cmd, self.session) + } +} diff --git a/src/channels.rs b/src/channels.rs deleted file mode 100644 index c1ed5db..0000000 --- a/src/channels.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::goval; -use prost::Message; -use serde; -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct IPCMessage { - pub bytes: Vec, - pub session: i32, -} - -impl IPCMessage { - pub fn from_cmd(cmd: goval::Command, session: i32) -> IPCMessage { - let mut bytes = Vec::new(); - bytes.reserve(cmd.encoded_len()); - cmd.encode(&mut bytes).unwrap(); - - IPCMessage { bytes, session } - } - - pub fn to_cmd(&self) -> Result { - Ok(goval::Command::decode(&*self.bytes)?) - } - - pub fn replace_cmd(&self, cmd: goval::Command) -> IPCMessage { - IPCMessage::from_cmd(cmd, self.session) - } -} diff --git a/src/config.rs b/src/config.rs index e4d7b4d..2e72a81 100644 --- a/src/config.rs +++ b/src/config.rs @@ -10,7 +10,7 @@ message ToolchainConfigs { use std::collections::HashMap; -use homeval::goval; +use goval; pub use serde::{Deserialize, Serialize}; pub mod toolchain { diff --git a/src/goval_server.rs b/src/goval_server.rs index 93a340d..c023409 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -1,75 +1,49 @@ use axum::{ extract::{ - State, - Path, - ConnectInfo, - ws::{ - WebSocket, - WebSocketUpgrade, - Message as WsMessage, - } + ws::{Message as WsMessage, WebSocket, WebSocketUpgrade}, + ConnectInfo, Path, State, }, - response::{Response, IntoResponse}, + response::{IntoResponse, Response}, routing::get, - Router + Router, }; #[cfg(feature = "fun-stuff")] use chrono::Datelike; -use deno_core::Snapshot; -use deno_core::error::AnyError; -use homeval::goval; -use homeval::goval::Command; +use anyhow::Result; +use goval::Command; +use homeval_services::ServiceMetadata; use prost::Message; -use tokio::sync::mpsc::UnboundedSender; use std::{net::SocketAddr, sync::LazyLock}; -use std::sync::Arc; +use tokio::sync::{mpsc::UnboundedSender, Mutex}; use futures_util::{SinkExt, StreamExt}; -use log::{error, info, trace, warn, debug, as_serde, as_display, as_error, as_debug}; +use log::{as_debug, as_display, as_error, as_serde, debug, error, info, trace, warn}; use tokio::sync::mpsc; use crate::{ - MAX_CHANNEL, - CHANNEL_METADATA, - CHANNEL_MESSAGES, - PROCCESS_CHANNEL_TO_ID, - SESSION_CHANNELS, - SESSION_CLIENT_INFO, - LAST_SESSION_USING_CHANNEL, - IMPLEMENTED_SERVICES, - SESSION_MAP, - MAX_SESSION, - CHANNEL_SESSIONS, + CHANNEL_MESSAGES, CHANNEL_METADATA, CHANNEL_SESSIONS, LAST_SESSION_USING_CHANNEL, MAX_SESSION, + PROCCESS_CHANNEL_TO_ID, SESSION_CHANNELS, SESSION_CLIENT_INFO, SESSION_MAP, }; use crate::{ - channels::IPCMessage, - deno_extension::{ - make_extension, - JsMessage, - Service - }, - parse_paseto::{ - parse, - ClientInfo - }, - services + parse_paseto::{parse, ClientInfo}, + IPCMessage, JsMessage, }; #[derive(Clone)] struct AppState { - sender: UnboundedSender + sender: UnboundedSender, } static DEFAULT_REPLY: &str = "(づ ◕‿◕ )づ Hello there"; -pub async fn start_server() -> Result<(), AnyError> { +pub async fn start_server() -> Result<()> { let addr = std::env::args() .nth(1) .unwrap_or_else(|| "127.0.0.1:8080".to_string()); - + let (tx, mut rx) = mpsc::unbounded_channel::(); let app = Router::new() @@ -80,12 +54,15 @@ pub async fn start_server() -> Result<(), AnyError> { tokio::spawn(async move { axum::Server::bind(&addr.parse().unwrap()) - .serve(app.into_make_service_with_connect_info::()) - .await.unwrap() + .serve(app.into_make_service_with_connect_info::()) + .await + .unwrap() }); + let max_channel = Mutex::new(0); + while let Some(message) = rx.recv().await { - handle_message(message, &SESSION_MAP).await; + handle_message(message, &SESSION_MAP, &max_channel).await; } Ok(()) @@ -117,334 +94,339 @@ async fn on_wsv2_upgrade(socket: WebSocket, token: String, state: AppState, addr session_recv, session_id, parse(&token).await.unwrap_or(ClientInfo::default()), - addr - ).await { + addr, + ) + .await + { Ok(_) => {} Err(err) => { error!(error = as_display!(err); "accept_connection errored") } }; - } async fn wsv2( ConnectInfo(addr): ConnectInfo, Path(token): Path, ws: WebSocketUpgrade, - State(state): State + State(state): State, ) -> Response { ws.on_upgrade(move |socket| on_wsv2_upgrade(socket, token, state, addr)) } -async fn handle_message(message: IPCMessage, session_map: &LazyLock>>>) { +async fn handle_message( + message: IPCMessage, + session_map: &LazyLock< + tokio::sync::RwLock>>, + >, + max_channel: &Mutex, +) { let cmd: Command; - match message.to_cmd() { - Err(err) => { - error!( - error = as_error!(err); - "An error occured when decoding message in the main loop" - ); - return; - } - Ok(res) => cmd = res, + match message.to_cmd() { + Err(err) => { + error!( + error = as_error!(err); + "An error occured when decoding message in the main loop" + ); + return; } + Ok(res) => cmd = res, + } - let cmd_body: goval::command::Body; + let cmd_body: goval::command::Body; - match cmd.body { - None => { - error!(command = as_debug!(cmd); "MISSING COMMAND BODY"); - return; - } - Some(body) => cmd_body = body, + match cmd.body { + None => { + error!(command = as_debug!(cmd); "MISSING COMMAND BODY"); + return; } + Some(body) => cmd_body = body, + } - if cmd.channel == 0 { - match cmd_body { - goval::command::Body::Ping(_) => { - let mut pong = goval::Command::default(); - pong.body = Some(goval::command::Body::Pong(goval::Pong::default())); - pong.r#ref = cmd.r#ref; - pong.channel = 0; - - if let Some(sender) = session_map.read().await.get(&message.session) { - match sender.send(message.replace_cmd(pong)) { - Ok(_) => {} - Err(err) => { - error!(error = as_error!(err);"Error occured while sending Pong"); - } + if cmd.channel == 0 { + match cmd_body { + goval::command::Body::Ping(_) => { + let mut pong = goval::Command::default(); + pong.body = Some(goval::command::Body::Pong(goval::Pong::default())); + pong.r#ref = cmd.r#ref; + pong.channel = 0; + + if let Some(sender) = session_map.read().await.get(&message.session) { + match sender.send(message.replace_cmd(pong)) { + Ok(_) => {} + Err(err) => { + error!(error = as_error!(err);"Error occured while sending Pong"); } - } else { - error!("Missing session queue when sending Pong") } + } else { + error!("Missing session queue when sending Pong") } - goval::command::Body::OpenChan(open_chan) => { - if IMPLEMENTED_SERVICES.contains(&open_chan.service) { - let mut found = false; - let mut channel_id_held = 0; - - let attach = open_chan.action() - == goval::open_channel::Action::AttachOrCreate - || open_chan.action() == goval::open_channel::Action::Attach - || open_chan.service == "git"; // git is just use for replspace api stuff - // from what I can tell, so its just easier to have it as one instance. - let create = open_chan.action() - == goval::open_channel::Action::AttachOrCreate - || open_chan.action() == goval::open_channel::Action::Create; - if attach { - let metadata = CHANNEL_METADATA.read().await; - for (id, channel) in metadata.iter() { - if channel.name.is_some() - && channel.name.clone().unwrap_or("".to_string()) - == open_chan.name - && channel.service.clone() == open_chan.service - { - found = true; - channel_id_held = id.clone(); - continue; - } + } + goval::command::Body::OpenChan(open_chan) => { + let searcher: &str = &open_chan.service; + if homeval_services::IMPLEMENTED_SERVICES.contains(&searcher) { + let mut found = false; + let mut channel_id_held = 0; + + let attach = open_chan.action() == goval::open_channel::Action::AttachOrCreate + || open_chan.action() == goval::open_channel::Action::Attach + || open_chan.service == "git"; // git is just use for replspace api stuff + // from what I can tell, so its just easier to have it as one instance. + let create = open_chan.action() == goval::open_channel::Action::AttachOrCreate + || open_chan.action() == goval::open_channel::Action::Create; + if attach { + let metadata = CHANNEL_METADATA.read().await; + for (id, channel) in metadata.iter() { + if channel.name.is_some() + && channel.name.clone().unwrap_or("".to_string()) == open_chan.name + && channel.service.clone() == open_chan.service + { + found = true; + channel_id_held = id.clone(); + continue; } } + } - if !found && create { - trace!("executing openchan main block"); - let service = open_chan.service.clone(); - let mut max_channel = MAX_CHANNEL.lock().await; - *max_channel += 1; - let channel_id = max_channel.clone(); - channel_id_held = channel_id.clone(); - drop(max_channel); - - let _channel_name: Option; - - if open_chan.name.len() > 0 { - _channel_name = Some(open_chan.name); - } else { - _channel_name = None; - } + if !found && create { + trace!("executing openchan main block"); + let service = open_chan.service.clone(); + let mut max_channel = max_channel.lock().await; + *max_channel += 1; + let channel_id = max_channel.clone(); + channel_id_held = channel_id.clone(); + drop(max_channel); + + let _channel_name: Option; + + if open_chan.name.len() > 0 { + _channel_name = Some(open_chan.name); + } else { + _channel_name = None; + } - let service_data = Service { - service: service.clone(), - id: channel_id, - name: _channel_name, - }; - - trace!(channel = channel_id; "Awaiting queue write"); - - CHANNEL_MESSAGES.write().await.insert( - channel_id_held, - Arc::new(deadqueue::unlimited::Queue::new()), - ); - - let mut metadata = CHANNEL_METADATA.write().await; - metadata.insert(channel_id_held, service_data.clone()); - drop(metadata); - trace!(channel = channel_id_held; "Added channel to queue list"); - - tokio::task::spawn_blocking(move || { - let local = tokio::task::LocalSet::new(); - - let rt = tokio::runtime::Handle::current(); - rt.block_on(async { - local - .run_until(async { - let mod_path = - &format!("services/{}.js", open_chan.service); - trace!( - path = mod_path, - service = open_chan.service; - "Loading module path" - ); - let main_module: deno_core::url::Url; - let main_module_res = deno_core::resolve_path( - mod_path, - std::env::current_dir().unwrap().as_path(), - ); - match main_module_res { - Err(err) => { - error!(error = as_error!(err); "Error resolving js module"); - return; - } - Ok(result) => { - main_module = result; - } + let service_data = ServiceMetadata { + service: service.clone(), + id: channel_id, + name: _channel_name, + }; + + trace!(channel = channel_id; "Awaiting queue write"); + + CHANNEL_MESSAGES.write().await.insert( + channel_id_held, + std::sync::Arc::new(deadqueue::unlimited::Queue::new()), + ); + + let mut metadata = CHANNEL_METADATA.write().await; + metadata.insert(channel_id_held, service_data.clone()); + drop(metadata); + trace!(channel = channel_id_held; "Added channel to queue list"); + + /* + tokio::task::spawn_blocking(move || { + let local = tokio::task::LocalSet::new(); + + let rt = tokio::runtime::Handle::current(); + rt.block_on(async { + local + .run_until(async { + let mod_path = + &format!("services/{}.js", open_chan.service); + trace!( + path = mod_path, + service = open_chan.service; + "Loading module path" + ); + let main_module: deno_core::url::Url; + let main_module_res = deno_core::resolve_path( + mod_path, + std::env::current_dir().unwrap().as_path(), + ); + match main_module_res { + Err(err) => { + error!(error = as_error!(err); "Error resolving js module"); + return; } - - let mut js_runtime = deno_core::JsRuntime::new( - deno_core::RuntimeOptions { - startup_snapshot: Some(Snapshot::Static( - homeval::HOMEVAL_JS_SNAPSHOT, - )), - module_loader: Some(std::rc::Rc::new( - deno_core::FsModuleLoader, - )), - extensions: vec![make_extension()], - ..Default::default() - }, - ); - - js_runtime - .execute_script( - "[goval::generated::globals]", - format!( - "globalThis.serviceInfo = {};", - serde_json::to_string(&service_data) - .unwrap() - ) - .into(), - ) - .unwrap(); - - let mod_id = js_runtime - .load_main_module( - &main_module, - services::get_module_core(open_chan.service.clone()) - .expect("Error fetching module code"), + Ok(result) => { + main_module = result; + } + } + + let mut js_runtime = deno_core::JsRuntime::new( + deno_core::RuntimeOptions { + startup_snapshot: Some(Snapshot::Static( + homeval::HOMEVAL_JS_SNAPSHOT, + )), + module_loader: Some(std::rc::Rc::new( + deno_core::FsModuleLoader, + )), + extensions: vec![make_extension()], + ..Default::default() + }, + ); + + js_runtime + .execute_script( + "[goval::generated::globals]", + format!( + "globalThis.serviceInfo = {};", + serde_json::to_string(&service_data) + .unwrap() ) - .await - .unwrap(); - - let result = js_runtime.mod_evaluate(mod_id); - - match js_runtime.run_event_loop(false).await { - Ok(_) => {}, - Err(err) => { - error!(service = open_chan.service, err = as_display!(err); "Got error in v8 thread for service") - } + .into(), + ) + .unwrap(); + + let mod_id = js_runtime + .load_main_module( + &main_module, + services::get_module_core(open_chan.service.clone()) + .expect("Error fetching module code"), + ) + .await + .unwrap(); + + let result = js_runtime.mod_evaluate(mod_id); + + match js_runtime.run_event_loop(false).await { + Ok(_) => {}, + Err(err) => { + error!(service = open_chan.service, err = as_display!(err); "Got error in v8 thread for service") } - - match result.await { - Ok(inner) => { - match inner { - Ok(_) => {}, - Err(err) => { - error!(service = open_chan.service, err = as_display!(err); "Got error in v8 thread for service") - } + } + + match result.await { + Ok(inner) => { + match inner { + Ok(_) => {}, + Err(err) => { + error!(service = open_chan.service, err = as_display!(err); "Got error in v8 thread for service") } - }, - Err(err) => { - error!(service = open_chan.service, err = as_error!(err); "Got error in v8 thread for service") } - } + }, + Err(err) => { + error!(service = open_chan.service, err = as_error!(err); "Got error in v8 thread for service") + } + } - trace!(service = as_debug!(service_data); "Service v8 isolate stopped"); - }) - .await; - }); + trace!(service = as_debug!(service_data); "Service v8 isolate stopped"); + }) + .await; }); - found = true; - } + }); + */ + found = true; + } - if !found { - error!("Couldnt make channel"); - let mut protocol_error = goval::Command::default(); - let mut _inner = goval::ProtocolError::default(); - _inner.text = "Could not create / attach channel".to_string(); - - protocol_error.body = Some(goval::command::Body::ProtocolError(_inner)); - protocol_error.r#ref = cmd.r#ref; - protocol_error.channel = 0; - - session_map - .read() - .await - .get(&message.session) - .unwrap() - .send(message.replace_cmd(protocol_error)) - .unwrap(); - return; - } + if !found { + error!("Couldnt make channel"); + let mut protocol_error = goval::Command::default(); + let mut _inner = goval::ProtocolError::default(); + _inner.text = "Could not create / attach channel".to_string(); - let mut open_chan_res = goval::Command::default(); - let mut _open_res = goval::OpenChannelRes::default(); - _open_res.state = goval::open_channel_res::State::Created.into(); - _open_res.id = channel_id_held; - open_chan_res.body = Some(goval::command::Body::OpenChanRes(_open_res)); - open_chan_res.r#ref = cmd.r#ref; - open_chan_res.channel = 0; + protocol_error.body = Some(goval::command::Body::ProtocolError(_inner)); + protocol_error.r#ref = cmd.r#ref; + protocol_error.channel = 0; session_map .read() .await .get(&message.session) .unwrap() - .send(message.replace_cmd(open_chan_res)) + .send(message.replace_cmd(protocol_error)) .unwrap(); + return; + } - let msg_read = CHANNEL_MESSAGES.read().await; + let mut open_chan_res = goval::Command::default(); + let mut _open_res = goval::OpenChannelRes::default(); + _open_res.state = goval::open_channel_res::State::Created.into(); + _open_res.id = channel_id_held; + open_chan_res.body = Some(goval::command::Body::OpenChanRes(_open_res)); + open_chan_res.r#ref = cmd.r#ref; + open_chan_res.channel = 0; - let queue = msg_read.get(&channel_id_held).unwrap().clone(); + session_map + .read() + .await + .get(&message.session) + .unwrap() + .send(message.replace_cmd(open_chan_res)) + .unwrap(); - drop(msg_read); + let msg_read = CHANNEL_MESSAGES.read().await; - queue.push(JsMessage::Attach(message.session)); + let queue = msg_read.get(&channel_id_held).unwrap().clone(); - - let mut guard = CHANNEL_SESSIONS - .write() - .await; + drop(msg_read); - match guard.get_mut(&channel_id_held) { - Some(arr) => { - arr.push(message.session); - } - None => { - guard.insert(channel_id_held, vec![message.session]); - } - } + queue.push(JsMessage::Attach(message.session)); - drop(guard); + let mut guard = CHANNEL_SESSIONS.write().await; - SESSION_CHANNELS - .write() - .await - .entry(message.session) - .and_modify(|channels| channels.push(channel_id_held)); - } else { - warn!( - service = open_chan.service; - "Missing service requested by openChan" - ) + match guard.get_mut(&channel_id_held) { + Some(arr) => { + arr.push(message.session); + } + None => { + guard.insert(channel_id_held, vec![message.session]); + } } + + drop(guard); + + SESSION_CHANNELS + .write() + .await + .entry(message.session) + .and_modify(|channels| channels.push(channel_id_held)); + } else { + warn!( + service = open_chan.service; + "Missing service requested by openChan" + ) } - goval::command::Body::CloseChan(close_chan) => { - // TODO: follow close_chan.action - tokio::spawn(detach_channel(close_chan.id, message.session, false)); - } - _ => {} } - } else { - // Directly deal with Command::Input, should be faster - if let goval::command::Body::Input(input) = cmd_body { - if let Some(pty_id) = PROCCESS_CHANNEL_TO_ID.read().await.get(&cmd.channel) { - let mut to_continue = false; - if let Some(queue) = crate::PROCCESS_WRITE_MESSAGES.read().await.get(&pty_id) { - queue.push(input); - to_continue = true; - } else { - error!(pty_id = pty_id; "Couldn't find pty to write to"); - } - if to_continue { - return; - } + goval::command::Body::CloseChan(close_chan) => { + // TODO: follow close_chan.action + tokio::spawn(detach_channel(close_chan.id, message.session, false)); + } + _ => {} + } + } else { + // Directly deal with Command::Input, should be faster + if let goval::command::Body::Input(input) = cmd_body { + if let Some(pty_id) = PROCCESS_CHANNEL_TO_ID.read().await.get(&cmd.channel) { + let mut to_continue = false; + if let Some(queue) = crate::PROCCESS_WRITE_MESSAGES.read().await.get(&pty_id) { + queue.push(input); + to_continue = true; + } else { + error!(pty_id = pty_id; "Couldn't find pty to write to"); + } + + if to_continue { + return; } } + } - let msg_lock = CHANNEL_MESSAGES.read().await; + let msg_lock = CHANNEL_MESSAGES.read().await; - let queue = msg_lock.get(&cmd.channel).unwrap().clone(); + let queue = msg_lock.get(&cmd.channel).unwrap().clone(); - drop(msg_lock); + drop(msg_lock); - queue.push(JsMessage::IPC(message.clone())); + queue.push(JsMessage::IPC(message.clone())); - let mut hashmap_lock = LAST_SESSION_USING_CHANNEL.write().await; + let mut hashmap_lock = LAST_SESSION_USING_CHANNEL.write().await; - hashmap_lock.insert(cmd.channel, message.session); + hashmap_lock.insert(cmd.channel, message.session); - drop(hashmap_lock); - } + drop(hashmap_lock); + } } async fn detach_channel(channel: i32, session: i32, forced: bool) { @@ -454,7 +436,7 @@ async fn detach_channel(channel: i32, session: i32, forced: bool) { .write() .await .entry(session) - .and_modify(|channels| channels.retain(|chan: &i32| { chan.clone() != channel })); + .and_modify(|channels| channels.retain(|chan: &i32| chan.clone() != channel)); let msg_lock = CHANNEL_MESSAGES.read().await; @@ -473,8 +455,8 @@ async fn detach_channel(channel: i32, session: i32, forced: bool) { trace!("Done waiting for sessions lock"); match guard.get_mut(&channel) { - Some(arr) => { - arr.retain(|sess| { sess.clone() != session }); + Some(arr) => { + arr.retain(|sess| sess.clone() != session); if arr.len() == 0 { trace!(channel = channel; "Shutting down channel"); queue.push(JsMessage::Shutdown(true)); @@ -491,7 +473,6 @@ async fn detach_channel(channel: i32, session: i32, forced: bool) { } None => { warn!(channel = channel; "Missing CHANNEL_SESSIONS"); - } } @@ -500,11 +481,8 @@ async fn detach_channel(channel: i32, session: i32, forced: bool) { async fn send_message( message: goval::Command, - stream: &mut futures_util::stream::SplitSink< - WebSocket, - WsMessage, - >, -) -> Result<(), AnyError> { + stream: &mut futures_util::stream::SplitSink, +) -> Result<()> { let mut buf = Vec::new(); buf.reserve(message.encoded_len()); message.encode(&mut buf)?; @@ -518,8 +496,8 @@ async fn accept_connection( mut sent: mpsc::UnboundedReceiver, session: i32, client: ClientInfo, - addr: SocketAddr -) -> Result<(), AnyError> { + addr: SocketAddr, +) -> Result<()> { info!(peer_address = as_display!(addr); "New connection"); info!(client = as_serde!(client); "New client"); diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index c9bc433..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Include the `goval` module, which is generated from goval.proto. -pub mod goval { - include!(concat!(env!("OUT_DIR"), "/goval.rs")); -} diff --git a/src/main.rs b/src/main.rs index 699cdaa..711c67e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,5 @@ #![feature(lazy_cell)] -use deno_extension::messaging::ReplspaceMessage; -use homeval::goval; -use serde::{Deserialize, Serialize}; - use std::sync::LazyLock; use std::time::Instant; use std::{collections::HashMap, io::Error, sync::Arc}; @@ -11,37 +7,7 @@ use std::{collections::HashMap, io::Error, sync::Arc}; use log::{debug, info}; use tokio::sync::{mpsc, Mutex, RwLock}; -mod channels; -use channels::IPCMessage; - -// mod deno_extension; -// use deno_extension::{JsMessage, Service}; - -struct Service {} -#[derive(Serialize, Deserialize, Clone)] -#[serde(rename_all = "camelCase")] -pub enum JsMessage { - #[serde(rename = "ipc")] - IPC(IPCMessage), - Attach(i32), - Detach(i32), - Close(i32), - ProcessDead(u32, i32), - CmdDead(i32), - Replspace(i32, ReplspaceMessage), // session, message - Shutdown(bool), // Shutdown the service, value has to be true so that runtime.js can match it in an if check -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "camelCase")] -pub enum ReplspaceMessage { - GithubTokenReq(String), // nonce - OpenFileReq(String, bool, String), // file, wait for close, nonce - OpenMultipleFiles(Vec, String), // files, nonce - - GithubTokenRes(String), // token - OpenFileRes, -} +use homeval_services::{IPCMessage, JsMessage, ReplspaceMessage, ServiceMetadata}; mod parse_paseto; use parse_paseto::ClientInfo; @@ -66,7 +32,6 @@ pub static DOTREPLIT_CONFIG: LazyLock = LazyLock::new(|| { }); static MAX_SESSION: LazyLock> = LazyLock::new(|| Mutex::new(0)); -static MAX_CHANNEL: LazyLock> = LazyLock::new(|| Mutex::new(0)); static SESSION_CHANNELS: LazyLock>>> = LazyLock::new(|| RwLock::new(HashMap::new())); @@ -75,7 +40,7 @@ static SESSION_CLIENT_INFO: LazyLock>> = static CHANNEL_MESSAGES: LazyLock< RwLock>>>, > = LazyLock::new(|| RwLock::new(HashMap::new())); -static CHANNEL_METADATA: LazyLock>> = +static CHANNEL_METADATA: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); static CHANNEL_SESSIONS: LazyLock>>> = LazyLock::new(|| RwLock::new(HashMap::new())); @@ -105,7 +70,7 @@ mod database; #[cfg(feature = "database")] pub use database::DATABASE; -// mod goval_server; +mod goval_server; #[tokio::main] async fn main() -> Result<(), Error> { @@ -129,7 +94,7 @@ async fn main() -> Result<(), Error> { #[cfg(feature = "repldb")] tokio::spawn(repldb_server::start_server()); - // goval_server::start_server().await.unwrap(); + goval_server::start_server().await.unwrap(); Ok(()) } diff --git a/src/parse_paseto.rs b/src/parse_paseto.rs index b1c7a0f..86c847e 100644 --- a/src/parse_paseto.rs +++ b/src/parse_paseto.rs @@ -1,6 +1,6 @@ use anyhow::Result; use base64::{engine::general_purpose, Engine as _}; -use homeval::goval; +use goval; use prost::Message; use serde::{Deserialize, Serialize}; use std::io::Error; From 276159708a7e1aa1e1eccd4cec87a61c5e1850bd Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Thu, 22 Jun 2023 21:08:16 -0700 Subject: [PATCH 004/103] feat(services): Pure rust gcsfiles --- Cargo.lock | 112 ++++++++-- protobuf/build.rs | 2 +- services/Cargo.toml | 4 + services/src/chat.rs | 28 ++- services/src/gcsfiles.rs | 136 ++++++++++++ services/src/lib.rs | 106 +++++++-- services/src/traits.rs | 32 ++- services/src/types.rs | 99 +++++++-- src/goval_server.rs | 452 +++++++++++++++++---------------------- src/main.rs | 4 +- src/replspace_server.rs | 10 +- 11 files changed, 672 insertions(+), 313 deletions(-) create mode 100644 services/src/gcsfiles.rs diff --git a/Cargo.lock b/Cargo.lock index 9500eb8..8ca0547 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -502,16 +502,6 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df" -[[package]] -name = "ctor" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096" -dependencies = [ - "quote", - "syn 1.0.109", -] - [[package]] name = "deadqueue" version = "0.2.4" @@ -1296,11 +1286,10 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" dependencies = [ - "cfg-if", "serde", "value-bag", ] @@ -2533,10 +2522,14 @@ name = "services" version = "0.1.0" dependencies = [ "anyhow", + "async-trait", "deadqueue", + "log", "prost", "protobuf", "serde", + "serde_json", + "tokio", ] [[package]] @@ -2771,11 +2764,70 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "sval" -version = "1.0.0-alpha.5" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2faba619276044eec7cd160d87b15d9191fb9b9f7198440343d2144f760cf08" + +[[package]] +name = "sval_buffer" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a353d3cca10721384077c9643c3fafdd6ed2600e57933b8e45c0b580d97b25af" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee5fc7349e9f6cb2ab950046818f66ad3f2d7209ccc5dced93da19292a30273a" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f6ee7c7b87caf59549e9fe45d6a69c75c8019e79e212a835c5da0e92f0ba08" +checksum = "098fb51d5d6007bd2c3f0a23b79aa953d7c46bf943086ce51424c3187c40f9b1" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f01126a2783d767496f18f13af26ab2587881f6343368bb26dc62956a723d1c7" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_ref" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5854d9eaa7bd31840a850322591c59c5b547eb29c9a6ecee1989d6ef963312ce" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cdd25fc04c5e882787d62112591aa93efb5bdc2000b43164d29f08582bb85f7" dependencies = [ "serde", + "sval", + "sval_buffer", + "sval_fmt", ] [[package]] @@ -3271,16 +3323,38 @@ dependencies = [ [[package]] name = "value-bag" -version = "1.0.0-alpha.9" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55" +checksum = "a4d330786735ea358f3bc09eea4caa098569c1c93f342d9aca0514915022fe7e" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4735c95b4cca1447b448e2e2e87e98d7e7498f4da27e355cf7af02204521001d" dependencies = [ - "ctor", "erased-serde", "serde", "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859cb4f0ce7da6a118b559ba74b0e63bf569bea867c20ba457a6b1c886a04e97" +dependencies = [ "sval", - "version_check", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", ] [[package]] diff --git a/protobuf/build.rs b/protobuf/build.rs index a331467..a2b455e 100644 --- a/protobuf/build.rs +++ b/protobuf/build.rs @@ -2,7 +2,7 @@ use prost_build::Config; extern crate prost_build; fn main() { - println!("cargo:rerun-if-changed=src/goval.protobufs"); + println!("cargo:rerun-if-changed=src/goval.proto"); // Compile protobufs let mut config = Config::new(); diff --git a/services/Cargo.toml b/services/Cargo.toml index 0e53ab3..7efff09 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -7,10 +7,14 @@ edition = "2021" [dependencies] anyhow = "1.0.71" +async-trait = "0.1.68" deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } goval = { package = "protobuf", path = "../protobuf"} +log = "0.4.19" prost = "0.11.9" serde = "1.0.164" +serde_json = "1.0.97" +tokio = "1.28.2" [lib] name = "services" diff --git a/services/src/chat.rs b/services/src/chat.rs index f15e736..4008a3c 100644 --- a/services/src/chat.rs +++ b/services/src/chat.rs @@ -1,8 +1,32 @@ pub struct Chat {} +use crate::SendSessions; + use super::traits; +use anyhow::Result; +use async_trait::async_trait; +#[async_trait] impl traits::Service for Chat { - fn attach(self, session: i32) -> Option { - None + async fn open(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { + Ok(()) + } + + async fn message( + &mut self, + info: &super::types::ChannelInfo, + message: goval::Command, + session: i32, + ) -> Result> { + info.send(message, SendSessions::EveryoneExcept(session)) + .await?; + Ok(None) + } + + async fn attach( + &mut self, + _info: &super::types::ChannelInfo, + _session: i32, + ) -> Result> { + Ok(None) } } diff --git a/services/src/gcsfiles.rs b/services/src/gcsfiles.rs new file mode 100644 index 0000000..bd3f2ac --- /dev/null +++ b/services/src/gcsfiles.rs @@ -0,0 +1,136 @@ +pub struct GCSFiles {} + +use super::traits; +use anyhow::{format_err, Result}; +use async_trait::async_trait; +use log::{as_debug, as_error, warn}; +use tokio::{fs, io::AsyncWriteExt}; + +#[async_trait] +impl traits::Service for GCSFiles { + async fn message( + &mut self, + _info: &super::types::ChannelInfo, + message: goval::Command, + _session: i32, + ) -> Result> { + let body = match message.body.clone() { + None => return Err(format_err!("Expected command body")), + Some(body) => body, + }; + + match body { + goval::command::Body::Readdir(dir) => { + let parent = std::path::Path::new(&dir.path); + + let mut res: Vec = vec![]; + let mut iter = fs::read_dir(&parent).await?; + + while let Some(file) = iter.next_entry().await? { + let mut entry = goval::File::default(); + if let Some(str_path) = file.path().strip_prefix(parent)?.to_str() { + entry.path = str_path.to_string(); + + let ftype = file.metadata().await?; + if ftype.is_dir() { + entry.r#type = goval::file::Type::Directory.into(); + } else { + entry.r#type = goval::file::Type::Regular.into(); + } + + res.push(entry); + } else { + return Err(format_err!("Got none from Path#to_str in gcsfiles#readdir")); + } + } + + let mut ret = goval::Command::default(); + let mut _inner = goval::Files::default(); + _inner.files = res; + ret.body = Some(goval::command::Body::Files(_inner)); + Ok(Some(ret)) + } + goval::command::Body::Mkdir(dir) => { + fs::create_dir_all(dir.path).await?; + let mut ret = goval::Command::default(); + ret.body = Some(goval::command::Body::Ok(goval::Ok {})); + Ok(Some(ret)) + } + goval::command::Body::Read(file) => { + let contents; + if file.path == ".config/goval/info" { + let val = serde_json::json!({ + "server": "homeval", + "version": env!("CARGO_PKG_VERSION").to_string(), + "license": "AGPL", + "authors": vec!["PotentialStyx <62217716+PotentialStyx@users.noreply.github.com>"], + "repository": "https://github.com/goval-community/homeval", + "description": "", // TODO: do dis + "uptime": 0, // TODO: impl fo realz + "services": super::IMPLEMENTED_SERVICES.clone() + }); + + contents = val.to_string().as_bytes().to_vec(); + } else { + contents = match fs::read(&file.path).await { + Err(err) => { + warn!(error = as_error!(err); "Error reading file in gcsfiles"); + let mut ret = goval::Command::default(); + ret.body = Some(goval::command::Body::Error(format!( + "{}: no such file or directory", + file.path + ))); + + return Ok(Some(ret)); + } + Ok(contents) => contents, + } + } + let mut ret = goval::Command::default(); + let mut _inner = goval::File::default(); + _inner.content = contents; + _inner.path = file.path; + ret.body = Some(goval::command::Body::File(_inner)); + Ok(Some(ret)) + } + goval::command::Body::Remove(file) => { + let stat = fs::metadata(&file.path).await?; + if stat.is_dir() { + fs::remove_dir_all(&file.path).await? + } else { + fs::remove_file(&file.path).await? + } + + let mut ret = goval::Command::default(); + ret.body = Some(goval::command::Body::Ok(goval::Ok {})); + Ok(Some(ret)) + } + goval::command::Body::Move(move_req) => { + fs::rename(move_req.old_path, move_req.new_path).await?; + let mut ret = goval::Command::default(); + ret.body = Some(goval::command::Body::Ok(goval::Ok {})); + Ok(Some(ret)) + } + goval::command::Body::Write(_file) => { + let mut file = fs::OpenOptions::new() + .write(true) + .create(true) + .open(_file.path) + .await?; + file.set_len(0).await?; + file.write(&_file.content).await?; + let mut ret = goval::Command::default(); + ret.body = Some(goval::command::Body::Ok(goval::Ok {})); + Ok(Some(ret)) + } + goval::command::Body::Stat(_) => { + // TODO: impl + Ok(None) + } + _ => { + warn!(cmd = as_debug!(message); "Unknown gcsfiles command"); + Ok(None) + } + } + } +} diff --git a/services/src/lib.rs b/services/src/lib.rs index 8460dc4..190cb55 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -1,26 +1,108 @@ mod chat; +mod gcsfiles; mod traits; mod types; +use anyhow::format_err; +use anyhow::Result; +use log::as_display; +use log::error; +use std::collections::HashMap; pub use types::*; +enum LoopControl { + Cont, + Break, +} + pub struct Channel { - pub clients: Vec, - _inner: Box, + info: ChannelInfo, + _inner: Box, } +// Public functions impl Channel { - pub fn new( - _id: i32, - service: String, - name: Option, - read: deadqueue::unlimited::Queue, - ) -> Channel { - Channel { - clients: vec![], - _inner: Box::new(chat::Chat {}), + pub fn new(id: i32, service: String, name: Option) -> Result { + let channel: Box = match service.as_str() { + "chat" => Box::new(chat::Chat {}), + "gcsfiles" => Box::new(gcsfiles::GCSFiles {}), + _ => return Err(format_err!("Unknown service: {}", service)), + }; + + Ok(Channel { + info: ChannelInfo { + id, + name, + service, + clients: HashMap::new(), + }, + _inner: channel, + }) + } + + pub async fn start(&mut self, mut read: tokio::sync::mpsc::UnboundedReceiver) { + 'mainloop: while let Some(message) = read.recv().await { + match self.msg(message).await { + Ok(ctrl) => match ctrl { + LoopControl::Break => break 'mainloop, + LoopControl::Cont => {} + }, + Err(err) => { + error!(error = as_display!(err); "Error encountered in service") + } + } } } } -pub static IMPLEMENTED_SERVICES: &[&str] = &["chat"]; +// Private functions +impl Channel { + async fn msg(&mut self, message: ChannelMessage) -> Result { + match message { + ChannelMessage::Attach(session, sender) => self.attach(session, sender).await, + ChannelMessage::Detach(session) => self.detach(session).await, + ChannelMessage::IPC(ipc) => self.message(ipc.command, ipc.session).await, + ChannelMessage::ProcessDead(_, _) => todo!(), + ChannelMessage::CmdDead(_) => todo!(), + ChannelMessage::Replspace(_, _) => todo!(), + ChannelMessage::Shutdown => { + self._inner.shutdown(&self.info).await?; + Ok(LoopControl::Break) + } + } + } + + async fn message(&mut self, message: goval::Command, session: i32) -> Result { + match self + ._inner + .message(&self.info, message.clone(), session) + .await? + { + Some(mut msg) => { + msg.channel = self.info.id; + msg.r#ref = message.r#ref; + self.info.send(msg, SendSessions::Only(session)).await? + } + None => {} + } + Ok(LoopControl::Cont) + } + + async fn attach( + &mut self, + session: i32, + sender: tokio::sync::mpsc::UnboundedSender, + ) -> Result { + self.info.clients.insert(session, sender); + self._inner.attach(&self.info, session).await?; + Ok(LoopControl::Cont) + } + + async fn detach(&mut self, session: i32) -> Result { + self.info.clients.retain(|sess, _| sess != &session); + self._inner.detach(&self.info, session).await?; + Ok(LoopControl::Cont) + } +} + +pub static IMPLEMENTED_SERVICES: &[&str] = &["chat", "gcsfiles"]; diff --git a/services/src/traits.rs b/services/src/traits.rs index 5f879ae..56d4538 100644 --- a/services/src/traits.rs +++ b/services/src/traits.rs @@ -1,3 +1,33 @@ +use anyhow::Result; +use async_trait::async_trait; + +#[async_trait] pub(crate) trait Service { - fn attach(self, session: i32) -> Option; + async fn open(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { + Ok(()) + } + async fn shutdown(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { + Ok(()) + } + + async fn message( + &mut self, + _info: &super::types::ChannelInfo, + _message: goval::Command, + _session: i32, + ) -> Result> { + Ok(None) + } + + async fn attach( + &mut self, + _info: &super::types::ChannelInfo, + _session: i32, + ) -> Result> { + Ok(None) + } + + async fn detach(&mut self, _info: &super::types::ChannelInfo, _session: i32) -> Result<()> { + Ok(()) + } } diff --git a/services/src/types.rs b/services/src/types.rs index a5ae6fc..78cc3cb 100644 --- a/services/src/types.rs +++ b/services/src/types.rs @@ -1,7 +1,64 @@ +use std::collections::HashMap; + +use anyhow::Result; use goval; +use log::error; use prost::Message; use serde; use serde::{Deserialize, Serialize}; +use tokio::sync::mpsc; + +pub enum SendSessions { + Only(i32), + EveryoneExcept(i32), + Everyone, +} + +pub struct ChannelInfo { + pub id: i32, + pub clients: HashMap>, + pub service: String, + pub name: Option, +} + +impl ChannelInfo { + pub async fn send(&self, message: goval::Command, sessions: SendSessions) -> Result<()> { + let clients: Vec; + match sessions { + SendSessions::Everyone => { + let mut _clients = vec![]; + for client in self.clients.keys() { + _clients.push(client.clone()) + } + + clients = _clients; + } + SendSessions::EveryoneExcept(excluded) => { + let mut _clients = vec![]; + for client in self.clients.keys() { + if client != &excluded { + _clients.push(client.clone()) + } + } + + clients = _clients; + } + SendSessions::Only(session) => clients = vec![session], + } + + for client in clients { + if let Some(sender) = self.clients.get(&client) { + sender.send(IPCMessage { + command: message.clone(), + session: client, + })?; + } else { + error!("Missing session outbound message queue in op_send_msg") + } + } + Ok(()) + } +} #[derive(Clone)] pub struct ServiceMetadata { @@ -21,41 +78,43 @@ pub enum ReplspaceMessage { OpenFileRes, } -#[derive(Serialize, Deserialize, Clone)] -#[serde(rename_all = "camelCase")] -pub enum JsMessage { - #[serde(rename = "ipc")] +#[derive(Clone, Debug)] +pub enum ChannelMessage { IPC(IPCMessage), - Attach(i32), + Attach(i32, mpsc::UnboundedSender), Detach(i32), - Close(i32), ProcessDead(u32, i32), CmdDead(i32), Replspace(i32, ReplspaceMessage), // session, message - Shutdown(bool), // Shutdown the service, value has to be true so that runtime.js can match it in an if check + Shutdown, // Shutdown the service, value has to be true so that runtime.js can match it in an if check } -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Debug, Clone)] pub struct IPCMessage { - pub bytes: Vec, + pub command: goval::Command, pub session: i32, } impl IPCMessage { - pub fn from_cmd(cmd: goval::Command, session: i32) -> IPCMessage { - let mut bytes = Vec::new(); - bytes.reserve(cmd.encoded_len()); - cmd.encode(&mut bytes).unwrap(); - - IPCMessage { bytes, session } + pub fn replace_cmd(&self, cmd: goval::Command) -> IPCMessage { + IPCMessage { + command: cmd, + session: self.session, + } } - pub fn to_cmd(&self) -> Result { - Ok(goval::Command::decode(&*self.bytes)?) + pub fn to_bytes(&self) -> Vec { + self.command.encode_to_vec() } +} - pub fn replace_cmd(&self, cmd: goval::Command) -> IPCMessage { - IPCMessage::from_cmd(cmd, self.session) +impl TryFrom> for IPCMessage { + type Error = anyhow::Error; + + fn try_from(value: Vec) -> Result { + Ok(Self { + command: goval::Command::decode(value.as_slice())?, + session: 0, + }) } } diff --git a/src/goval_server.rs b/src/goval_server.rs index c023409..3c46a78 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -12,7 +12,7 @@ use axum::{ use chrono::Datelike; use anyhow::Result; -use goval::Command; +use goval::{Command, OpenChannel}; use homeval_services::ServiceMetadata; use prost::Message; use std::{net::SocketAddr, sync::LazyLock}; @@ -29,7 +29,7 @@ use crate::{ use crate::{ parse_paseto::{parse, ClientInfo}, - IPCMessage, JsMessage, + ChannelMessage, IPCMessage, }; #[derive(Clone)] @@ -121,17 +121,7 @@ async fn handle_message( >, max_channel: &Mutex, ) { - let cmd: Command; - match message.to_cmd() { - Err(err) => { - error!( - error = as_error!(err); - "An error occured when decoding message in the main loop" - ); - return; - } - Ok(res) => cmd = res, - } + let cmd: Command = message.clone().command; let cmd_body: goval::command::Body; @@ -163,235 +153,22 @@ async fn handle_message( } } goval::command::Body::OpenChan(open_chan) => { - let searcher: &str = &open_chan.service; - if homeval_services::IMPLEMENTED_SERVICES.contains(&searcher) { - let mut found = false; - let mut channel_id_held = 0; - - let attach = open_chan.action() == goval::open_channel::Action::AttachOrCreate - || open_chan.action() == goval::open_channel::Action::Attach - || open_chan.service == "git"; // git is just use for replspace api stuff - // from what I can tell, so its just easier to have it as one instance. - let create = open_chan.action() == goval::open_channel::Action::AttachOrCreate - || open_chan.action() == goval::open_channel::Action::Create; - if attach { - let metadata = CHANNEL_METADATA.read().await; - for (id, channel) in metadata.iter() { - if channel.name.is_some() - && channel.name.clone().unwrap_or("".to_string()) == open_chan.name - && channel.service.clone() == open_chan.service - { - found = true; - channel_id_held = id.clone(); - continue; - } - } - } - - if !found && create { - trace!("executing openchan main block"); - let service = open_chan.service.clone(); - let mut max_channel = max_channel.lock().await; - *max_channel += 1; - let channel_id = max_channel.clone(); - channel_id_held = channel_id.clone(); - drop(max_channel); - - let _channel_name: Option; - - if open_chan.name.len() > 0 { - _channel_name = Some(open_chan.name); - } else { - _channel_name = None; - } - - let service_data = ServiceMetadata { - service: service.clone(), - id: channel_id, - name: _channel_name, - }; - - trace!(channel = channel_id; "Awaiting queue write"); - - CHANNEL_MESSAGES.write().await.insert( - channel_id_held, - std::sync::Arc::new(deadqueue::unlimited::Queue::new()), - ); - - let mut metadata = CHANNEL_METADATA.write().await; - metadata.insert(channel_id_held, service_data.clone()); - drop(metadata); - trace!(channel = channel_id_held; "Added channel to queue list"); - - /* - tokio::task::spawn_blocking(move || { - let local = tokio::task::LocalSet::new(); - - let rt = tokio::runtime::Handle::current(); - rt.block_on(async { - local - .run_until(async { - let mod_path = - &format!("services/{}.js", open_chan.service); - trace!( - path = mod_path, - service = open_chan.service; - "Loading module path" - ); - let main_module: deno_core::url::Url; - let main_module_res = deno_core::resolve_path( - mod_path, - std::env::current_dir().unwrap().as_path(), - ); - match main_module_res { - Err(err) => { - error!(error = as_error!(err); "Error resolving js module"); - return; - } - Ok(result) => { - main_module = result; - } - } - - let mut js_runtime = deno_core::JsRuntime::new( - deno_core::RuntimeOptions { - startup_snapshot: Some(Snapshot::Static( - homeval::HOMEVAL_JS_SNAPSHOT, - )), - module_loader: Some(std::rc::Rc::new( - deno_core::FsModuleLoader, - )), - extensions: vec![make_extension()], - ..Default::default() - }, - ); - - js_runtime - .execute_script( - "[goval::generated::globals]", - format!( - "globalThis.serviceInfo = {};", - serde_json::to_string(&service_data) - .unwrap() - ) - .into(), - ) - .unwrap(); - - let mod_id = js_runtime - .load_main_module( - &main_module, - services::get_module_core(open_chan.service.clone()) - .expect("Error fetching module code"), - ) - .await - .unwrap(); - - let result = js_runtime.mod_evaluate(mod_id); - - match js_runtime.run_event_loop(false).await { - Ok(_) => {}, - Err(err) => { - error!(service = open_chan.service, err = as_display!(err); "Got error in v8 thread for service") - } - } - - match result.await { - Ok(inner) => { - match inner { - Ok(_) => {}, - Err(err) => { - error!(service = open_chan.service, err = as_display!(err); "Got error in v8 thread for service") - } - } - }, - Err(err) => { - error!(service = open_chan.service, err = as_error!(err); "Got error in v8 thread for service") - } - } - - trace!(service = as_debug!(service_data); "Service v8 isolate stopped"); - }) - .await; - }); - }); - */ - found = true; - } - - if !found { - error!("Couldnt make channel"); - let mut protocol_error = goval::Command::default(); - let mut _inner = goval::ProtocolError::default(); - _inner.text = "Could not create / attach channel".to_string(); - - protocol_error.body = Some(goval::command::Body::ProtocolError(_inner)); - protocol_error.r#ref = cmd.r#ref; - protocol_error.channel = 0; - - session_map - .read() - .await - .get(&message.session) - .unwrap() - .send(message.replace_cmd(protocol_error)) - .unwrap(); - return; - } - - let mut open_chan_res = goval::Command::default(); - let mut _open_res = goval::OpenChannelRes::default(); - _open_res.state = goval::open_channel_res::State::Created.into(); - _open_res.id = channel_id_held; - open_chan_res.body = Some(goval::command::Body::OpenChanRes(_open_res)); - open_chan_res.r#ref = cmd.r#ref; - open_chan_res.channel = 0; - - session_map - .read() - .await - .get(&message.session) - .unwrap() - .send(message.replace_cmd(open_chan_res)) - .unwrap(); - - let msg_read = CHANNEL_MESSAGES.read().await; - - let queue = msg_read.get(&channel_id_held).unwrap().clone(); - - drop(msg_read); - - queue.push(JsMessage::Attach(message.session)); - - let mut guard = CHANNEL_SESSIONS.write().await; - - match guard.get_mut(&channel_id_held) { - Some(arr) => { - arr.push(message.session); - } - None => { - guard.insert(channel_id_held, vec![message.session]); - } - } - - drop(guard); - - SESSION_CHANNELS - .write() - .await - .entry(message.session) - .and_modify(|channels| channels.push(channel_id_held)); - } else { - warn!( - service = open_chan.service; - "Missing service requested by openChan" - ) + if let Err(err) = open_channel(open_chan, message, max_channel, session_map).await { + error!(error = as_display!(err); "Error in open chan handler") } } goval::command::Body::CloseChan(close_chan) => { // TODO: follow close_chan.action - tokio::spawn(detach_channel(close_chan.id, message.session, false)); + tokio::spawn(async move { + match detach_channel(close_chan.id, message.session, true).await { + Ok(_) => {} + Err(err) => { + error!(error = as_display!(err), session = message.session, channel = close_chan.id; + "Error occured while detaching from channel") + } + } + }); } _ => {} } @@ -419,7 +196,9 @@ async fn handle_message( drop(msg_lock); - queue.push(JsMessage::IPC(message.clone())); + queue + .send(ChannelMessage::IPC(message.clone())) + .expect("TODO: deal with this"); let mut hashmap_lock = LAST_SESSION_USING_CHANNEL.write().await; @@ -429,7 +208,164 @@ async fn handle_message( } } -async fn detach_channel(channel: i32, session: i32, forced: bool) { +async fn open_channel( + open_chan: OpenChannel, + message: IPCMessage, + max_channel: &Mutex, + session_map: &LazyLock< + tokio::sync::RwLock>>, + >, +) -> Result<()> { + let searcher: &str = &open_chan.service; + if homeval_services::IMPLEMENTED_SERVICES.contains(&searcher) { + let mut found = false; + let mut channel_id_held = 0; + + let attach = open_chan.action() == goval::open_channel::Action::AttachOrCreate + || open_chan.action() == goval::open_channel::Action::Attach + || open_chan.service == "git"; // git is just use for replspace api stuff + // from what I can tell, so its just easier to have it as one instance. + let create = open_chan.action() == goval::open_channel::Action::AttachOrCreate + || open_chan.action() == goval::open_channel::Action::Create; + if attach { + let metadata = CHANNEL_METADATA.read().await; + for (id, channel) in metadata.iter() { + if channel.name.is_some() + && channel.name.clone().unwrap_or("".to_string()) == open_chan.name + && channel.service.clone() == open_chan.service + { + found = true; + channel_id_held = id.clone(); + continue; + } + } + } + + if !found && create { + trace!("executing openchan main block"); + let service = open_chan.service.clone(); + let mut max_channel = max_channel.lock().await; + *max_channel += 1; + let channel_id = max_channel.clone(); + channel_id_held = channel_id.clone(); + drop(max_channel); + + let _channel_name: Option; + + if open_chan.name.len() > 0 { + _channel_name = Some(open_chan.name); + } else { + _channel_name = None; + } + + let service_data = ServiceMetadata { + service: service.clone(), + id: channel_id, + name: _channel_name.clone(), + }; + + trace!(channel = channel_id; "Awaiting queue write"); + + let (writer, reader) = mpsc::unbounded_channel(); + + CHANNEL_MESSAGES + .write() + .await + .insert(channel_id_held, writer); + + let mut metadata = CHANNEL_METADATA.write().await; + metadata.insert(channel_id_held, service_data.clone()); + drop(metadata); + trace!(channel = channel_id_held; "Added channel to queue list"); + + tokio::spawn(async move { + let mut channel = + homeval_services::Channel::new(channel_id, service, _channel_name).unwrap(); + channel.start(reader).await; + }); + found = true; + } + + if !found { + error!("Couldnt make channel"); + let mut protocol_error = goval::Command::default(); + let mut _inner = goval::ProtocolError::default(); + _inner.text = "Could not create / attach channel".to_string(); + + protocol_error.body = Some(goval::command::Body::ProtocolError(_inner)); + protocol_error.r#ref = message.command.r#ref.clone(); + protocol_error.channel = 0; + + session_map + .read() + .await + .get(&message.session) + .unwrap() + .send(message.replace_cmd(protocol_error)) + .unwrap(); + return Ok(()); + } + + let mut open_chan_res = goval::Command::default(); + let mut _open_res = goval::OpenChannelRes::default(); + _open_res.state = goval::open_channel_res::State::Created.into(); + _open_res.id = channel_id_held; + open_chan_res.body = Some(goval::command::Body::OpenChanRes(_open_res)); + open_chan_res.r#ref = message.command.r#ref.clone(); + open_chan_res.channel = 0; + + session_map + .read() + .await + .get(&message.session) + .unwrap() + .send(message.replace_cmd(open_chan_res)) + .unwrap(); + + let msg_read = CHANNEL_MESSAGES.read().await; + + let queue = msg_read.get(&channel_id_held).unwrap().clone(); + + drop(msg_read); + + queue.send(ChannelMessage::Attach( + message.session, + SESSION_MAP + .read() + .await + .get(&message.session) + .expect("TODO: deal with this") + .clone(), + ))?; + + let mut guard = CHANNEL_SESSIONS.write().await; + + match guard.get_mut(&channel_id_held) { + Some(arr) => { + arr.push(message.session); + } + None => { + guard.insert(channel_id_held, vec![message.session]); + } + } + + drop(guard); + + SESSION_CHANNELS + .write() + .await + .entry(message.session) + .and_modify(|channels| channels.push(channel_id_held)); + } else { + warn!( + service = open_chan.service; + "Missing service requested by openChan" + ) + } + Ok(()) +} + +async fn detach_channel(channel: i32, session: i32, forced: bool) -> Result<()> { trace!(session = session, channel = channel, forced = forced; "Client is closing a channel"); SESSION_CHANNELS @@ -444,11 +380,7 @@ async fn detach_channel(channel: i32, session: i32, forced: bool) { drop(msg_lock); - if forced { - queue.push(JsMessage::Close(session)); - } else { - queue.push(JsMessage::Detach(session)); - } + queue.send(ChannelMessage::Detach(session))?; trace!("Waiting for sessions lock"); let mut guard = CHANNEL_SESSIONS.write().await; @@ -459,7 +391,7 @@ async fn detach_channel(channel: i32, session: i32, forced: bool) { arr.retain(|sess| sess.clone() != session); if arr.len() == 0 { trace!(channel = channel; "Shutting down channel"); - queue.push(JsMessage::Shutdown(true)); + queue.send(ChannelMessage::Shutdown)?; tokio::spawn(async move { CHANNEL_METADATA.write().await.remove(&channel); @@ -477,6 +409,7 @@ async fn detach_channel(channel: i32, session: i32, forced: bool) { } drop(guard); + Ok(()) } async fn send_message( @@ -550,10 +483,20 @@ async fn accept_connection( match _msg { Ok(msg) => match msg { WsMessage::Binary(buf) => { - if let Err(err) = propagate.send(IPCMessage { - bytes: buf, - session, - }) { + let _message: anyhow::Result = buf.try_into(); + let message: IPCMessage; + match _message { + Ok(mut msg) => { + msg.session = session; + message = msg + } + Err(err) => { + error!(error = as_display!(err), session = session; "Error decoding message from client"); + continue; + } + } + + if let Err(err) = propagate.send(message) { error!(session = session, error = as_error!(err); "An error occured when enqueing message to global message queue") } } @@ -562,7 +505,14 @@ async fn accept_connection( for _channel in SESSION_CHANNELS.read().await.get(&session).unwrap().iter() { let channel = _channel.clone(); - tokio::spawn(detach_channel(channel, session, true)); + tokio::spawn(async move { + match detach_channel(channel, session, true).await { + Ok(_) => {} + Err(err) => { + error!(error = as_display!(err), session = session, channel = channel; "Error occured while detaching from channel") + } + } + }); } SESSION_MAP.write().await.remove(&session); @@ -583,7 +533,7 @@ async fn accept_connection( }); while let Some(i) = sent.recv().await { - match write.send(WsMessage::Binary(i.bytes)).await { + match write.send(WsMessage::Binary(i.to_bytes())).await { Ok(_) => {} Err(err) => { error!( diff --git a/src/main.rs b/src/main.rs index 711c67e..8ec265c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,7 +7,7 @@ use std::{collections::HashMap, io::Error, sync::Arc}; use log::{debug, info}; use tokio::sync::{mpsc, Mutex, RwLock}; -use homeval_services::{IPCMessage, JsMessage, ReplspaceMessage, ServiceMetadata}; +use homeval_services::{ChannelMessage, IPCMessage, ReplspaceMessage, ServiceMetadata}; mod parse_paseto; use parse_paseto::ClientInfo; @@ -38,7 +38,7 @@ static SESSION_CHANNELS: LazyLock>>> = static SESSION_CLIENT_INFO: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); static CHANNEL_MESSAGES: LazyLock< - RwLock>>>, + RwLock>>, > = LazyLock::new(|| RwLock::new(HashMap::new())); static CHANNEL_METADATA: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); diff --git a/src/replspace_server.rs b/src/replspace_server.rs index d75856a..d7901c8 100644 --- a/src/replspace_server.rs +++ b/src/replspace_server.rs @@ -10,7 +10,7 @@ use serde::{Deserialize, Serialize}; use textnonce::TextNonce; use tokio::sync::oneshot::channel; -use crate::{JsMessage, ReplspaceMessage}; +use crate::{ChannelMessage, ReplspaceMessage}; pub async fn start_server() -> Result<()> { info!("Replspace api server listening on: 127.0.0.1:8283"); @@ -63,12 +63,12 @@ async fn get_gh_token(_query: Option>) -> (StatusCode, Jso drop(callback_table); - let to_send = JsMessage::Replspace(session, ReplspaceMessage::GithubTokenReq(nonce)); + let to_send = ChannelMessage::Replspace(session, ReplspaceMessage::GithubTokenReq(nonce)); let msg_lock = crate::CHANNEL_MESSAGES.read().await; for channel in msg_lock.values() { - channel.push(to_send.clone()); + channel.send(to_send.clone()).expect("TODO: deal with this"); } // let queue = msg_lock.get(&cmd.channel).unwrap().clone(); @@ -169,7 +169,7 @@ async fn open_file(Json(query): Json) -> (StatusCode, Json) -> (StatusCode, Json Date: Fri, 23 Jun 2023 11:56:51 -0700 Subject: [PATCH 005/103] feat(services): Pure rust presence implementation --- Cargo.lock | 3 +- Cargo.toml | 2 +- services/Cargo.toml | 3 +- services/src/chat.rs | 3 +- services/src/lib.rs | 20 ++++- services/src/presence.rs | 162 +++++++++++++++++++++++++++++++++++++++ services/src/traits.rs | 3 + services/src/types.rs | 32 +++++++- src/goval_server.rs | 17 ++-- src/main.rs | 3 +- src/parse_paseto.rs | 24 +----- 11 files changed, 229 insertions(+), 43 deletions(-) create mode 100644 services/src/presence.rs diff --git a/Cargo.lock b/Cargo.lock index 8ca0547..88dfc6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -973,7 +973,7 @@ dependencies = [ [[package]] name = "homeval" -version = "0.2.0" +version = "0.3.0" dependencies = [ "anyhow", "axum", @@ -2526,6 +2526,7 @@ dependencies = [ "deadqueue", "log", "prost", + "prost-types", "protobuf", "serde", "serde_json", diff --git a/Cargo.toml b/Cargo.toml index 265b026..091a638 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "homeval" -version = "0.2.0" +version = "0.3.0" edition = "2021" license = "AGPL-3.0-only" authors = ["PotentialStyx <62217716+PotentialStyx@users.noreply.github.com>"] diff --git a/services/Cargo.toml b/services/Cargo.toml index 7efff09..6276029 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -10,8 +10,9 @@ anyhow = "1.0.71" async-trait = "0.1.68" deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } goval = { package = "protobuf", path = "../protobuf"} -log = "0.4.19" +log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } prost = "0.11.9" +prost-types = "0.11.9" serde = "1.0.164" serde_json = "1.0.97" tokio = "1.28.2" diff --git a/services/src/chat.rs b/services/src/chat.rs index 4008a3c..6bab3c2 100644 --- a/services/src/chat.rs +++ b/services/src/chat.rs @@ -1,5 +1,5 @@ pub struct Chat {} -use crate::SendSessions; +use crate::{ClientInfo, SendSessions}; use super::traits; use anyhow::Result; @@ -25,6 +25,7 @@ impl traits::Service for Chat { async fn attach( &mut self, _info: &super::types::ChannelInfo, + _client: ClientInfo, _session: i32, ) -> Result> { Ok(None) diff --git a/services/src/lib.rs b/services/src/lib.rs index 190cb55..6a660d6 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -1,5 +1,6 @@ mod chat; mod gcsfiles; +mod presence; mod traits; mod types; @@ -26,6 +27,7 @@ impl Channel { let channel: Box = match service.as_str() { "chat" => Box::new(chat::Chat {}), "gcsfiles" => Box::new(gcsfiles::GCSFiles {}), + "presence" => Box::new(presence::Presence::new()), _ => return Err(format_err!("Unknown service: {}", service)), }; @@ -35,6 +37,7 @@ impl Channel { name, service, clients: HashMap::new(), + sessions: HashMap::new(), }, _inner: channel, }) @@ -59,7 +62,9 @@ impl Channel { impl Channel { async fn msg(&mut self, message: ChannelMessage) -> Result { match message { - ChannelMessage::Attach(session, sender) => self.attach(session, sender).await, + ChannelMessage::Attach(session, client, sender) => { + self.attach(session, client, sender).await + } ChannelMessage::Detach(session) => self.detach(session).await, ChannelMessage::IPC(ipc) => self.message(ipc.command, ipc.session).await, ChannelMessage::ProcessDead(_, _) => todo!(), @@ -79,7 +84,6 @@ impl Channel { .await? { Some(mut msg) => { - msg.channel = self.info.id; msg.r#ref = message.r#ref; self.info.send(msg, SendSessions::Only(session)).await? } @@ -91,18 +95,26 @@ impl Channel { async fn attach( &mut self, session: i32, + client: ClientInfo, sender: tokio::sync::mpsc::UnboundedSender, ) -> Result { + self.info.sessions.insert(session, client.clone()); self.info.clients.insert(session, sender); - self._inner.attach(&self.info, session).await?; + match self._inner.attach(&self.info, client, session).await? { + None => {} + Some(msg) => { + self.info.send(msg, SendSessions::Only(session)).await?; + } + } Ok(LoopControl::Cont) } async fn detach(&mut self, session: i32) -> Result { + self.info.sessions.retain(|sess, _| sess != &session); self.info.clients.retain(|sess, _| sess != &session); self._inner.detach(&self.info, session).await?; Ok(LoopControl::Cont) } } -pub static IMPLEMENTED_SERVICES: &[&str] = &["chat", "gcsfiles"]; +pub static IMPLEMENTED_SERVICES: &[&str] = &["chat", "gcsfiles", "presence"]; diff --git a/services/src/presence.rs b/services/src/presence.rs new file mode 100644 index 0000000..f4f62bd --- /dev/null +++ b/services/src/presence.rs @@ -0,0 +1,162 @@ +pub struct Presence { + users: Vec, + files: HashMap, +} +use crate::{ClientInfo, SendSessions}; +use log::{as_debug, info, warn}; +use std::{ + collections::HashMap, + time::{SystemTime, UNIX_EPOCH}, +}; + +use super::traits; +use anyhow::{format_err, Result}; +use async_trait::async_trait; + +impl Presence { + pub fn new() -> Self { + Self { + users: vec![], + files: HashMap::new(), + } + } +} + +#[async_trait] +impl traits::Service for Presence { + async fn open(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { + Ok(()) + } + + async fn message( + &mut self, + info: &super::types::ChannelInfo, + message: goval::Command, + session: i32, + ) -> Result> { + let body = match message.body.clone() { + None => return Err(format_err!("Expected command body")), + Some(body) => body, + }; + + match body { + goval::command::Body::FollowUser(follow) => { + let mut follow_notif = goval::Command::default(); + + follow_notif.body = Some(goval::command::Body::FollowUser(goval::FollowUser { + session, + })); + + info.send(follow_notif, SendSessions::Only(follow.session)) + .await?; + Ok(None) + } + goval::command::Body::UnfollowUser(unfollow) => { + let mut unfollow_notif = goval::Command::default(); + + unfollow_notif.body = + Some(goval::command::Body::UnfollowUser(goval::UnfollowUser { + session, + })); + + info.send(unfollow_notif, SendSessions::Only(unfollow.session)) + .await?; + Ok(None) + } + goval::command::Body::OpenFile(file) => { + let user = info.sessions.get(&session).unwrap(); + + let mut file_notif = goval::Command::default(); + + let timestamp = Some(prost_types::Timestamp { + seconds: SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() as i64, + nanos: 0, + }); + + let _inner = goval::FileOpened { + user_id: user.id, + file: file.file, + session, + timestamp, + }; + + file_notif.body = Some(goval::command::Body::FileOpened(_inner)); + + info.send(file_notif, SendSessions::EveryoneExcept(session)) + .await?; + + Ok(None) + } + _ => { + warn!(cmd = as_debug!(message); "Unknown presence command"); + Ok(None) + } + } + } + + async fn attach( + &mut self, + info: &super::types::ChannelInfo, + client: ClientInfo, + session: i32, + ) -> Result> { + let mut roster = goval::Command::default(); + let mut _inner = goval::Roster::default(); + + let mut files = vec![]; + + for file in self.files.values() { + files.push(file.clone()) + } + + _inner.files = files; + _inner.user = self.users.clone(); + roster.body = Some(goval::command::Body::Roster(_inner)); + + let mut user = goval::User::default(); + user.session = session; + user.id = client.id; + user.name = client.username; + + let mut join = goval::Command::default(); + join.body = Some(goval::command::Body::Join(user.clone())); + + info.send(join, SendSessions::EveryoneExcept(session)) + .await?; + + self.users.push(user); + + Ok(Some(roster)) + } + + async fn detach(&mut self, info: &super::types::ChannelInfo, session: i32) -> Result<()> { + self.files.remove(&session); + let mut part = goval::Command::default(); + let mut flag = false; + + let users = self.users.clone(); + for (idx, user) in users.iter().enumerate() { + if user.session == session { + flag = true; + part.body = Some(goval::command::Body::Part(user.clone())); + self.users.swap_remove(idx); + break; + } + } + + if !flag { + return Err(format_err!( + "Session {} missing from user list in Presence#detach", + session + )); + } + + info!(e = as_debug!(part); "Presence#detach"); + info.send(part, SendSessions::EveryoneExcept(session)) + .await?; + Ok(()) + } +} diff --git a/services/src/traits.rs b/services/src/traits.rs index 56d4538..2c5c134 100644 --- a/services/src/traits.rs +++ b/services/src/traits.rs @@ -1,6 +1,8 @@ use anyhow::Result; use async_trait::async_trait; +use crate::ClientInfo; + #[async_trait] pub(crate) trait Service { async fn open(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { @@ -22,6 +24,7 @@ pub(crate) trait Service { async fn attach( &mut self, _info: &super::types::ChannelInfo, + _client: ClientInfo, _session: i32, ) -> Result> { Ok(None) diff --git a/services/src/types.rs b/services/src/types.rs index 78cc3cb..5752e0e 100644 --- a/services/src/types.rs +++ b/services/src/types.rs @@ -19,13 +19,16 @@ pub struct ChannelInfo { pub clients: HashMap>, pub service: String, pub name: Option, + pub sessions: HashMap, } impl ChannelInfo { - pub async fn send(&self, message: goval::Command, sessions: SendSessions) -> Result<()> { + pub async fn send(&self, mut message: goval::Command, sessions: SendSessions) -> Result<()> { let clients: Vec; + message.channel = self.id; match sessions { SendSessions::Everyone => { + message.session = 0; let mut _clients = vec![]; for client in self.clients.keys() { _clients.push(client.clone()) @@ -34,6 +37,7 @@ impl ChannelInfo { clients = _clients; } SendSessions::EveryoneExcept(excluded) => { + message.session = -excluded; let mut _clients = vec![]; for client in self.clients.keys() { if client != &excluded { @@ -43,7 +47,10 @@ impl ChannelInfo { clients = _clients; } - SendSessions::Only(session) => clients = vec![session], + SendSessions::Only(session) => { + message.session = session; + clients = vec![session] + } } for client in clients { @@ -81,7 +88,7 @@ pub enum ReplspaceMessage { #[derive(Clone, Debug)] pub enum ChannelMessage { IPC(IPCMessage), - Attach(i32, mpsc::UnboundedSender), + Attach(i32, ClientInfo, mpsc::UnboundedSender), Detach(i32), ProcessDead(u32, i32), CmdDead(i32), @@ -118,3 +125,22 @@ impl TryFrom> for IPCMessage { }) } } + +#[derive(Clone, Debug)] +pub struct ClientInfo { + pub is_secure: bool, + + pub username: String, + pub id: u32, +} + +impl Default for ClientInfo { + fn default() -> Self { + Self { + is_secure: false, + + username: "homeval-user".to_owned(), + id: 23054564, + } + } +} diff --git a/src/goval_server.rs b/src/goval_server.rs index 3c46a78..af1c5da 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -13,13 +13,13 @@ use chrono::Datelike; use anyhow::Result; use goval::{Command, OpenChannel}; -use homeval_services::ServiceMetadata; +use homeval_services::{ClientInfo, ServiceMetadata}; use prost::Message; use std::{net::SocketAddr, sync::LazyLock}; use tokio::sync::{mpsc::UnboundedSender, Mutex}; use futures_util::{SinkExt, StreamExt}; -use log::{as_debug, as_display, as_error, as_serde, debug, error, info, trace, warn}; +use log::{as_debug, as_display, as_error, debug, error, info, trace, warn}; use tokio::sync::mpsc; use crate::{ @@ -27,10 +27,7 @@ use crate::{ PROCCESS_CHANNEL_TO_ID, SESSION_CHANNELS, SESSION_CLIENT_INFO, SESSION_MAP, }; -use crate::{ - parse_paseto::{parse, ClientInfo}, - ChannelMessage, IPCMessage, -}; +use crate::{parse_paseto::parse, ChannelMessage, IPCMessage}; #[derive(Clone)] struct AppState { @@ -330,6 +327,12 @@ async fn open_channel( queue.send(ChannelMessage::Attach( message.session, + SESSION_CLIENT_INFO + .read() + .await + .get(&message.session) + .unwrap() + .clone(), SESSION_MAP .read() .await @@ -433,7 +436,7 @@ async fn accept_connection( ) -> Result<()> { info!(peer_address = as_display!(addr); "New connection"); - info!(client = as_serde!(client); "New client"); + info!(client = as_debug!(client); "New client"); SESSION_CLIENT_INFO .write() diff --git a/src/main.rs b/src/main.rs index 8ec265c..4b8f98a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,10 +7,9 @@ use std::{collections::HashMap, io::Error, sync::Arc}; use log::{debug, info}; use tokio::sync::{mpsc, Mutex, RwLock}; -use homeval_services::{ChannelMessage, IPCMessage, ReplspaceMessage, ServiceMetadata}; +use homeval_services::{ChannelMessage, ClientInfo, IPCMessage, ReplspaceMessage, ServiceMetadata}; mod parse_paseto; -use parse_paseto::ClientInfo; mod config; use config::dotreplit::DotReplit; diff --git a/src/parse_paseto.rs b/src/parse_paseto.rs index 86c847e..6accb46 100644 --- a/src/parse_paseto.rs +++ b/src/parse_paseto.rs @@ -1,8 +1,8 @@ use anyhow::Result; use base64::{engine::general_purpose, Engine as _}; use goval; +use homeval_services::ClientInfo; use prost::Message; -use serde::{Deserialize, Serialize}; use std::io::Error; #[cfg(feature = "verify_connections")] @@ -15,28 +15,6 @@ static KEYS: tokio::sync::OnceCell> = #[cfg(feature = "verify_connections")] use log::{as_display, warn}; -#[derive(Debug, Serialize, Deserialize, Clone)] -#[serde(rename_all = "camelCase")] -pub struct ClientInfo { - // In the future this will indicate if the jwt signature was legit or not - // For now it'll always be false - pub is_secure: bool, - - pub username: String, - pub id: u32, -} - -impl ClientInfo { - pub fn default() -> ClientInfo { - ClientInfo { - is_secure: false, - - username: "homeval-user".to_owned(), - id: 23054564, - } - } -} - fn parse_noverify(token: &str) -> Result<(Vec, bool)> { let token_parts = token.split(".").collect::>(); if token_parts.len() < 3 { From 0c3e1dab67af15c7728389e05b93005bba3b3f7d Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 24 Jun 2023 13:16:58 -0700 Subject: [PATCH 006/103] feat(services): Pure rust ot implementation --- Cargo.lock | 393 +++----------------------------------------- Cargo.toml | 9 +- services/Cargo.toml | 2 + services/src/lib.rs | 4 +- services/src/ot.rs | 244 +++++++++++++++++++++++++++ 5 files changed, 274 insertions(+), 378 deletions(-) create mode 100644 services/src/ot.rs diff --git a/Cargo.lock b/Cargo.lock index 88dfc6f..fa31112 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -332,12 +332,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" -[[package]] -name = "bytesize" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38fcc2979eff34a4b84e1cf9a1e3da42a7d44b3b690a40cdcb23e3d556cfb2e5" - [[package]] name = "cc" version = "1.0.79" @@ -458,13 +452,12 @@ dependencies = [ ] [[package]] -name = "crossbeam-channel" -version = "0.5.8" +name = "crc32fast" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" dependencies = [ "cfg-if", - "crossbeam-utils", ] [[package]] @@ -549,12 +542,6 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" -[[package]] -name = "downcast-rs" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" - [[package]] name = "ed25519-compact" version = "2.0.4" @@ -641,38 +628,6 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" -[[package]] -name = "file-id" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13be71e6ca82e91bc0cb862bebaac0b2d1924a5a1d970c822b2f98b63fda8c3" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "filedescriptor" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7199d965852c3bac31f779ef99cbb4537f80e952e2d6aa0ffeb30cce00f4f46e" -dependencies = [ - "libc", - "thiserror", - "winapi", -] - -[[package]] -name = "filetime" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall 0.2.16", - "windows-sys 0.48.0", -] - [[package]] name = "fixedbitset" version = "0.4.2" @@ -709,15 +664,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fsevent-sys" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" -dependencies = [ - "libc", -] - [[package]] name = "funty" version = "2.0.0" @@ -989,12 +935,9 @@ dependencies = [ "futures-util", "hyper", "hyper-tls", - "include_directory", "log", "migration", - "notify-debouncer-full", "pasetors", - "portable-pty", "prost", "prost-types", "protobuf", @@ -1003,11 +946,8 @@ dependencies = [ "serde", "serde_json", "services", - "similar", - "systemstat", "textnonce", "tokio", - "tokio-stream", "toml 0.7.4", ] @@ -1121,26 +1061,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "include_directory" -version = "0.1.1" -source = "git+https://github.com/goval-community/include_directory.git?rev=bea5083a#bea5083ad2fc87b98c0f425b82484d12134c5534" -dependencies = [ - "include_directory_macros", - "mime", -] - -[[package]] -name = "include_directory_macros" -version = "0.1.0" -source = "git+https://github.com/goval-community/include_directory.git?rev=bea5083a#bea5083ad2fc87b98c0f425b82484d12134c5534" -dependencies = [ - "mime", - "new_mime_guess", - "proc-macro2", - "quote", -] - [[package]] name = "indexmap" version = "1.9.3" @@ -1151,26 +1071,6 @@ dependencies = [ "hashbrown 0.12.3", ] -[[package]] -name = "inotify" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" -dependencies = [ - "bitflags", - "inotify-sys", - "libc", -] - -[[package]] -name = "inotify-sys" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" -dependencies = [ - "libc", -] - [[package]] name = "instant" version = "0.1.12" @@ -1191,15 +1091,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "ioctl-rs" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7970510895cee30b3e9128319f2cefd4bde883a39f38baa279567ba3a7eb97d" -dependencies = [ - "libc", -] - [[package]] name = "is-terminal" version = "0.4.7" @@ -1236,26 +1127,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "kqueue" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8fc60ba15bf51257aa9807a48a61013db043fcf3a78cb0d916e8e396dcad98" -dependencies = [ - "kqueue-sys", - "libc", -] - -[[package]] -name = "kqueue-sys" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587" -dependencies = [ - "bitflags", - "libc", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -1324,15 +1195,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "memoffset" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" -dependencies = [ - "autocfg", -] - [[package]] name = "migration" version = "0.1.0" @@ -1360,7 +1222,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", - "log", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -1389,30 +1250,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "new_mime_guess" -version = "4.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d684d1b59e0dc07b37e2203ef576987473288f530082512aff850585c61b1f" -dependencies = [ - "mime", - "unicase", -] - -[[package]] -name = "nix" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" -dependencies = [ - "autocfg", - "bitflags", - "cfg-if", - "libc", - "memoffset", - "pin-utils", -] - [[package]] name = "nom" version = "7.1.3" @@ -1423,37 +1260,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "notify" -version = "6.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5738a2795d57ea20abec2d6d76c6081186709c0024187cd5977265eda6598b51" -dependencies = [ - "bitflags", - "crossbeam-channel", - "filetime", - "fsevent-sys", - "inotify", - "kqueue", - "libc", - "mio", - "walkdir", - "windows-sys 0.45.0", -] - -[[package]] -name = "notify-debouncer-full" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4812c1eb49be776fb8df4961623bdc01ec9dfdc1abe8211ceb09150a2e64219" -dependencies = [ - "file-id", - "notify", - "parking_lot 0.12.1", - "serde", - "walkdir", -] - [[package]] name = "num-bigint" version = "0.4.3" @@ -1629,7 +1435,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets 0.48.0", + "windows-targets", ] [[package]] @@ -1753,27 +1559,6 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" -[[package]] -name = "portable-pty" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806ee80c2a03dbe1a9fb9534f8d19e4c0546b790cde8fd1fea9d6390644cb0be" -dependencies = [ - "anyhow", - "bitflags", - "downcast-rs", - "filedescriptor", - "lazy_static", - "libc", - "log", - "nix", - "serial", - "shared_library", - "shell-words", - "winapi", - "winreg", -] - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2114,6 +1899,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ropey" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53ce7a2c43a32e50d666e33c5a80251b31147bb4b49024bcab11fb6f20c671ed" +dependencies = [ + "smallvec", + "str_indices", +] + [[package]] name = "rust_decimal" version = "1.30.0" @@ -2179,15 +1974,6 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - [[package]] name = "schannel" version = "0.1.21" @@ -2475,59 +2261,19 @@ dependencies = [ "serde", ] -[[package]] -name = "serial" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1237a96570fc377c13baa1b88c7589ab66edced652e43ffb17088f003db3e86" -dependencies = [ - "serial-core", - "serial-unix", - "serial-windows", -] - -[[package]] -name = "serial-core" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f46209b345401737ae2125fe5b19a77acce90cd53e1658cda928e4fe9a64581" -dependencies = [ - "libc", -] - -[[package]] -name = "serial-unix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f03fbca4c9d866e24a459cbca71283f545a37f8e3e002ad8c70593871453cab7" -dependencies = [ - "ioctl-rs", - "libc", - "serial-core", - "termios", -] - -[[package]] -name = "serial-windows" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c6d3b776267a75d31bbdfd5d36c0ca051251caafc285827052bc53bcdc8162" -dependencies = [ - "libc", - "serial-core", -] - [[package]] name = "services" version = "0.1.0" dependencies = [ "anyhow", "async-trait", + "crc32fast", "deadqueue", "log", "prost", "prost-types", "protobuf", + "ropey", "serde", "serde_json", "tokio", @@ -2564,22 +2310,6 @@ dependencies = [ "lazy_static", ] -[[package]] -name = "shared_library" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" -dependencies = [ - "lazy_static", - "libc", -] - -[[package]] -name = "shell-words" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" - [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -2595,12 +2325,6 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" -[[package]] -name = "similar" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" - [[package]] name = "siphasher" version = "0.3.10" @@ -2747,6 +2471,12 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "str_indices" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f026164926842ec52deb1938fae44f83dfdb82d0a5b0270c5bd5935ab74d6dd" + [[package]] name = "stringprep" version = "0.1.2" @@ -2859,20 +2589,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -[[package]] -name = "systemstat" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a24aec24a9312c83999a28e3ef9db7e2afd5c64bf47725b758cdc1cafd5b0bd2" -dependencies = [ - "bytesize", - "lazy_static", - "libc", - "nom", - "time 0.3.22", - "winapi", -] - [[package]] name = "tap" version = "1.0.1" @@ -2902,15 +2618,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "termios" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a" -dependencies = [ - "libc", -] - [[package]] name = "textnonce" version = "1.0.0" @@ -3248,15 +2955,6 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" version = "0.3.13" @@ -3370,16 +3068,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "walkdir" -version = "2.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" -dependencies = [ - "same-file", - "winapi-util", -] - [[package]] name = "want" version = "0.3.1" @@ -3548,7 +3236,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.0", + "windows-targets", ] [[package]] @@ -3566,37 +3254,13 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets", ] [[package]] @@ -3707,15 +3371,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - [[package]] name = "wyz" version = "0.5.1" diff --git a/Cargo.toml b/Cargo.toml index 091a638..4195ddd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,18 +31,11 @@ prost-types = "0.11.8" serde_json = "1.0.97" serde = "1.0.162" tokio = {version="1.26.0", features = ["full"]} -tokio-stream = { version = "0.1.14", features = ["fs"] } base64 = "0.21.0" -portable-pty = "0.8.1" - -include_directory = { git = "https://github.com/goval-community/include_directory.git", rev = "bea5083a" } futures = "0.3.28" axum = { version = "0.6.18", features = ["ws"] } -systemstat = "0.2.3" cpu-time = "1.0.0" -notify-debouncer-full = { version = "0.1.0", default-features = false, features = ["serde"] } deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } -similar = "2.2.1" toml = "0.7.4" textnonce = "1.0.0" @@ -58,4 +51,4 @@ sea-query = { version = "0.28.5", optional = true } pasetors = { version = "0.6.7", default-features = false, features = ["v2"], optional = true } hyper = { version = "0.14.26", features = ["http1", "http2", "client"], optional = true } hyper-tls = { version = "0.5.0", optional = true } -anyhow = "1.0.71" \ No newline at end of file +anyhow = "1.0.71" diff --git a/services/Cargo.toml b/services/Cargo.toml index 6276029..344cafd 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -8,11 +8,13 @@ edition = "2021" [dependencies] anyhow = "1.0.71" async-trait = "0.1.68" +crc32fast = { version = "1.3.2", features = ["nightly"] } deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } goval = { package = "protobuf", path = "../protobuf"} log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } prost = "0.11.9" prost-types = "0.11.9" +ropey = "1.6.0" serde = "1.0.164" serde_json = "1.0.97" tokio = "1.28.2" diff --git a/services/src/lib.rs b/services/src/lib.rs index 6a660d6..7d23980 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -1,5 +1,6 @@ mod chat; mod gcsfiles; +mod ot; mod presence; mod traits; mod types; @@ -28,6 +29,7 @@ impl Channel { "chat" => Box::new(chat::Chat {}), "gcsfiles" => Box::new(gcsfiles::GCSFiles {}), "presence" => Box::new(presence::Presence::new()), + "ot" => Box::new(ot::OT::new()), _ => return Err(format_err!("Unknown service: {}", service)), }; @@ -117,4 +119,4 @@ impl Channel { } } -pub static IMPLEMENTED_SERVICES: &[&str] = &["chat", "gcsfiles", "presence"]; +pub static IMPLEMENTED_SERVICES: &[&str] = &["chat", "gcsfiles", "presence", "ot"]; diff --git a/services/src/ot.rs b/services/src/ot.rs new file mode 100644 index 0000000..6cf063e --- /dev/null +++ b/services/src/ot.rs @@ -0,0 +1,244 @@ +pub struct OT { + version: u32, + contents: ropey::Rope, + path: String, + cursors: HashMap, + history: Vec, +} +use std::{ + collections::HashMap, + time::{SystemTime, UNIX_EPOCH}, +}; + +use crate::ClientInfo; + +use super::traits; +use anyhow::{format_err, Result}; +use async_trait::async_trait; +use log::{as_debug, warn}; +use tokio::fs; +impl OT { + pub fn new() -> OT { + OT { + version: 1, + contents: "".into(), + path: "".to_string(), + cursors: HashMap::new(), + history: vec![], + } + } +} + +#[async_trait] +impl traits::Service for OT { + async fn open(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { + Ok(()) + } + + async fn message( + &mut self, + info: &super::types::ChannelInfo, + message: goval::Command, + session: i32, + ) -> Result> { + let body = match message.body.clone() { + None => return Err(format_err!("Expected command body")), + Some(body) => body, + }; + + if &self.path == "" { + if let goval::command::Body::OtLinkFile(link_file) = body.clone() { + let path = link_file.file.unwrap().path; + match fs::metadata(path.clone()).await { + Err(_) => { + let mut error = goval::Command::default(); + error.body = Some(goval::command::Body::Error(format!( + "{}: no such file or directory", + path + ))); + return Ok(Some(error)); + } + Ok(_) => {} + }; + + self.path = path.clone(); + let byte_contents = fs::read(path.clone()).await?; + let crc32 = crc32fast::hash(byte_contents.as_slice()); + + self.contents = String::from_utf8(byte_contents.clone())?.into(); + + let timestamp = Some(prost_types::Timestamp { + seconds: SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() as i64, + nanos: 0, + }); + + let hist_item = goval::OtPacket { + spooky_version: self.version, + version: self.version, + op: vec![], + crc32, + committed: timestamp, + author: goval::ot_packet::Author::User.into(), + user_id: 23352071, + nonce: 0, + }; + + self.history.push(hist_item); + + let mut link_response = goval::Command::default(); + + let mut file = goval::File::default(); + file.path = path; + file.content = byte_contents; + + let _inner = goval::OtLinkFileResponse { + version: self.version, + linked_file: Some(file), + }; + link_response.body = Some(goval::command::Body::OtLinkFileResponse(_inner)); + + return Ok(Some(link_response)); + } else { + return Err(format_err!("Command sent before otLinkFile")); + } + } + + match body { + goval::command::Body::Ot(ot) => { + let mut cursor: usize = 0; + + for op in ot.op.clone() { + match op.op_component.unwrap() { + goval::ot_op_component::OpComponent::Skip(_skip) => { + let skip: usize = _skip.try_into()?; + if skip + cursor > self.contents.len_chars() { + let mut err = goval::Command::default(); + err.body = Some(goval::command::Body::Error( + "Invalid skip past bounds".to_string(), + )); + return Ok(Some(err)); + } + + cursor += skip + } + goval::ot_op_component::OpComponent::Delete(_delete) => { + let delete: usize = _delete.try_into()?; + if delete + cursor > self.contents.len_chars() { + let mut err = goval::Command::default(); + err.body = Some(goval::command::Body::Error( + "Invalid delete past bounds".to_string(), + )); + return Ok(Some(err)); + } + + self.contents.remove(cursor..(cursor + delete)) + } + goval::ot_op_component::OpComponent::Insert(insert) => { + self.contents.insert(cursor, &insert) + } + } + } + + let to_write = self.contents.to_string(); + self.version += 1; + let user_id = 22261053; + let crc32 = crc32fast::hash(to_write.as_bytes()); + + let packet = goval::OtPacket { + spooky_version: self.version, + version: self.version, + op: ot.op, + committed: None, + crc32, + nonce: 0, + user_id, + author: ot.author, + }; + + self.history.push(packet.clone()); + + let mut ot_notif = goval::Command::default(); + ot_notif.body = Some(goval::command::Body::Ot(packet)); + + info.send(ot_notif, crate::SendSessions::Everyone).await?; + + fs::write(&self.path, to_write).await?; + + let mut ok = goval::Command::default(); + ok.body = Some(goval::command::Body::Ok(goval::Ok {})); + Ok(Some(ok)) + } + goval::command::Body::OtNewCursor(cursor) => { + self.cursors.insert(cursor.id.clone(), cursor.clone()); + + let mut cursor_notif = goval::Command::default(); + + cursor_notif.body = Some(goval::command::Body::OtNewCursor(cursor)); + + info.send(cursor_notif, crate::SendSessions::EveryoneExcept(session)) + .await?; + Ok(None) + } + goval::command::Body::OtDeleteCursor(cursor) => { + self.cursors.remove(&cursor.id); + + let mut cursor_delete_notif = goval::Command::default(); + + cursor_delete_notif.body = Some(goval::command::Body::OtDeleteCursor(cursor)); + + info.send( + cursor_delete_notif, + crate::SendSessions::EveryoneExcept(session), + ) + .await?; + + Ok(None) + } + goval::command::Body::Flush(_) => { + let mut ok = goval::Command::default(); + ok.body = Some(goval::command::Body::Ok(goval::Ok {})); + Ok(Some(ok)) + } + _ => { + warn!(cmd = as_debug!(message); "Unknown ot command"); + Ok(None) + } + } + } + + async fn attach( + &mut self, + _info: &super::types::ChannelInfo, + _client: ClientInfo, + _session: i32, + ) -> Result> { + if &self.path == "" { + let mut cmd = goval::Command::default(); + cmd.body = Some(goval::command::Body::Otstatus(goval::OtStatus::default())); + return Ok(Some(cmd)); + } + let mut status = goval::Command::default(); + + let mut file = goval::File::default(); + file.path = self.path.clone(); + + let mut cursors = vec![]; + + for cursor in self.cursors.values() { + cursors.push(cursor.clone()) + } + + let _inner = goval::OtStatus { + contents: self.contents.to_string(), + version: self.version, + linked_file: Some(file), + cursors: cursors, + }; + status.body = Some(goval::command::Body::Otstatus(_inner)); + + Ok(Some(status)) + } +} From 1196742ffce6301dde1e228d123d9a388e16080c Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 26 Jun 2023 11:27:57 -0700 Subject: [PATCH 007/103] feat(services): Sync local file changes to homeval state --- Cargo.lock | 168 +++++++++++++++- services/Cargo.toml | 2 + services/src/chat.rs | 9 - services/src/lib.rs | 89 +++++---- services/src/ot.rs | 302 ++++++++++++++++++++++++++--- services/src/presence.rs | 3 +- services/src/traits.rs | 5 +- services/src/types.rs | 146 -------------- services/src/types/channel_info.rs | 67 +++++++ services/src/types/client.rs | 18 ++ services/src/types/fs_watcher.rs | 136 +++++++++++++ services/src/types/messaging.rs | 63 ++++++ services/src/types/mod.rs | 14 ++ services/src/types/service.rs | 6 + src/goval_server.rs | 5 +- 15 files changed, 794 insertions(+), 239 deletions(-) delete mode 100644 services/src/types.rs create mode 100644 services/src/types/channel_info.rs create mode 100644 services/src/types/client.rs create mode 100644 services/src/types/fs_watcher.rs create mode 100644 services/src/types/messaging.rs create mode 100644 services/src/types/mod.rs create mode 100644 services/src/types/service.rs diff --git a/Cargo.lock b/Cargo.lock index fa31112..fea9a57 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -460,6 +460,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + [[package]] name = "crossbeam-queue" version = "0.3.8" @@ -628,6 +638,27 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" +[[package]] +name = "file-id" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13be71e6ca82e91bc0cb862bebaac0b2d1924a5a1d970c822b2f98b63fda8c3" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "filetime" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.2.16", + "windows-sys 0.48.0", +] + [[package]] name = "fixedbitset" version = "0.4.2" @@ -664,6 +695,15 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + [[package]] name = "funty" version = "2.0.0" @@ -1071,6 +1111,26 @@ dependencies = [ "hashbrown 0.12.3", ] +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + [[package]] name = "instant" version = "0.1.12" @@ -1127,6 +1187,26 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kqueue" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c8fc60ba15bf51257aa9807a48a61013db043fcf3a78cb0d916e8e396dcad98" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587" +dependencies = [ + "bitflags", + "libc", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -1222,6 +1302,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", + "log", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -1260,6 +1341,36 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "notify" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5738a2795d57ea20abec2d6d76c6081186709c0024187cd5977265eda6598b51" +dependencies = [ + "bitflags", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "mio", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "notify-debouncer-full" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "416969970ec751a5d702a88c6cd19ac1332abe997fce43f96db0418550426241" +dependencies = [ + "file-id", + "notify", + "parking_lot 0.12.1", + "walkdir", +] + [[package]] name = "num-bigint" version = "0.4.3" @@ -1435,7 +1546,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets", + "windows-targets 0.48.0", ] [[package]] @@ -1974,6 +2085,15 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.21" @@ -2270,12 +2390,14 @@ dependencies = [ "crc32fast", "deadqueue", "log", + "notify-debouncer-full", "prost", "prost-types", "protobuf", "ropey", "serde", "serde_json", + "similar", "tokio", ] @@ -2325,6 +2447,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +[[package]] +name = "similar" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" + [[package]] name = "siphasher" version = "0.3.10" @@ -3068,6 +3196,16 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -3236,7 +3374,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets", + "windows-targets 0.48.0", ] [[package]] @@ -3254,13 +3392,37 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] diff --git a/services/Cargo.toml b/services/Cargo.toml index 344cafd..b85fabe 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -12,11 +12,13 @@ crc32fast = { version = "1.3.2", features = ["nightly"] } deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } goval = { package = "protobuf", path = "../protobuf"} log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } +notify-debouncer-full = { version = "0.2.0", default-features = false } prost = "0.11.9" prost-types = "0.11.9" ropey = "1.6.0" serde = "1.0.164" serde_json = "1.0.97" +similar = "2.2.1" tokio = "1.28.2" [lib] diff --git a/services/src/chat.rs b/services/src/chat.rs index 6bab3c2..9584323 100644 --- a/services/src/chat.rs +++ b/services/src/chat.rs @@ -21,13 +21,4 @@ impl traits::Service for Chat { .await?; Ok(None) } - - async fn attach( - &mut self, - _info: &super::types::ChannelInfo, - _client: ClientInfo, - _session: i32, - ) -> Result> { - Ok(None) - } } diff --git a/services/src/lib.rs b/services/src/lib.rs index 7d23980..f2dad3e 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -12,11 +12,6 @@ use log::error; use std::collections::HashMap; pub use types::*; -enum LoopControl { - Cont, - Break, -} - pub struct Channel { info: ChannelInfo, _inner: Box, @@ -24,34 +19,51 @@ pub struct Channel { // Public functions impl Channel { - pub fn new(id: i32, service: String, name: Option) -> Result { + pub async fn new(id: i32, service: String, name: Option) -> Result { let channel: Box = match service.as_str() { "chat" => Box::new(chat::Chat {}), "gcsfiles" => Box::new(gcsfiles::GCSFiles {}), "presence" => Box::new(presence::Presence::new()), - "ot" => Box::new(ot::OT::new()), + "ot" => Box::new(ot::OT::new().await?), _ => return Err(format_err!("Unknown service: {}", service)), }; + let info = ChannelInfo { + id, + name, + service, + clients: HashMap::new(), + sessions: HashMap::new(), + }; + Ok(Channel { - info: ChannelInfo { - id, - name, - service, - clients: HashMap::new(), - sessions: HashMap::new(), - }, + info, _inner: channel, }) } - pub async fn start(&mut self, mut read: tokio::sync::mpsc::UnboundedReceiver) { - 'mainloop: while let Some(message) = read.recv().await { - match self.msg(message).await { - Ok(ctrl) => match ctrl { - LoopControl::Break => break 'mainloop, - LoopControl::Cont => {} + pub async fn start(mut self, mut read: tokio::sync::mpsc::UnboundedReceiver) { + while let Some(message) = read.recv().await { + let result = match message { + ChannelMessage::Attach(session, client, sender) => { + self.attach(session, client, sender).await + } + ChannelMessage::Detach(session) => self.detach(session).await, + ChannelMessage::IPC(ipc) => self.message(ipc.command, ipc.session).await, + ChannelMessage::ProcessDead(_, _) => todo!(), + ChannelMessage::CmdDead(_) => todo!(), + ChannelMessage::Replspace(_, _) => todo!(), + ChannelMessage::Shutdown => match self._inner.shutdown(&self.info).await { + Ok(_) => break, + Err(err) => { + error!(error = as_display!(err); "Error encountered in Service#shutdown"); + break; + } }, + }; + + match result { + Ok(_) => {} Err(err) => { error!(error = as_display!(err); "Error encountered in service") } @@ -62,24 +74,7 @@ impl Channel { // Private functions impl Channel { - async fn msg(&mut self, message: ChannelMessage) -> Result { - match message { - ChannelMessage::Attach(session, client, sender) => { - self.attach(session, client, sender).await - } - ChannelMessage::Detach(session) => self.detach(session).await, - ChannelMessage::IPC(ipc) => self.message(ipc.command, ipc.session).await, - ChannelMessage::ProcessDead(_, _) => todo!(), - ChannelMessage::CmdDead(_) => todo!(), - ChannelMessage::Replspace(_, _) => todo!(), - ChannelMessage::Shutdown => { - self._inner.shutdown(&self.info).await?; - Ok(LoopControl::Break) - } - } - } - - async fn message(&mut self, message: goval::Command, session: i32) -> Result { + async fn message(&mut self, message: goval::Command, session: i32) -> Result<()> { match self ._inner .message(&self.info, message.clone(), session) @@ -91,7 +86,7 @@ impl Channel { } None => {} } - Ok(LoopControl::Cont) + Ok(()) } async fn attach( @@ -99,23 +94,27 @@ impl Channel { session: i32, client: ClientInfo, sender: tokio::sync::mpsc::UnboundedSender, - ) -> Result { + ) -> Result<()> { self.info.sessions.insert(session, client.clone()); - self.info.clients.insert(session, sender); - match self._inner.attach(&self.info, client, session).await? { + self.info.clients.insert(session, sender.clone()); + match self + ._inner + .attach(&self.info, client, session, sender) + .await? + { None => {} Some(msg) => { self.info.send(msg, SendSessions::Only(session)).await?; } } - Ok(LoopControl::Cont) + Ok(()) } - async fn detach(&mut self, session: i32) -> Result { + async fn detach(&mut self, session: i32) -> Result<()> { self.info.sessions.retain(|sess, _| sess != &session); self.info.clients.retain(|sess, _| sess != &session); self._inner.detach(&self.info, session).await?; - Ok(LoopControl::Cont) + Ok(()) } } diff --git a/services/src/ot.rs b/services/src/ot.rs index 6cf063e..69533f0 100644 --- a/services/src/ot.rs +++ b/services/src/ot.rs @@ -1,31 +1,53 @@ pub struct OT { - version: u32, - contents: ropey::Rope, + crc32: Arc>, + version: Arc>, + contents: Arc>, path: String, cursors: HashMap, - history: Vec, + history: Arc>>, + watcher: FSWatcher, + _sending_map: Arc>>>, } + use std::{ collections::HashMap, - time::{SystemTime, UNIX_EPOCH}, + sync::Arc, + time::{Duration, SystemTime, UNIX_EPOCH}, }; -use crate::ClientInfo; +use crate::{client::ClientInfo, fs_watcher::FSWatcher, FSEvent, IPCMessage}; use super::traits; use anyhow::{format_err, Result}; use async_trait::async_trait; -use log::{as_debug, warn}; -use tokio::fs; +use log::{as_debug, debug, error, warn, trace}; +use similar::TextDiff; +use tokio::{ + fs, + sync::{broadcast::error::RecvError, RwLock}, +}; + +enum LoopControl { + Cont(Result<()>), + Break, +} + impl OT { - pub fn new() -> OT { - OT { - version: 1, - contents: "".into(), + pub async fn new() -> Result { + let watcher = FSWatcher::new().await?; + + let chan = OT { + crc32: Arc::new(RwLock::new(0)), + version: Arc::new(RwLock::new(1)), + contents: Arc::new(RwLock::new("".into())), path: "".to_string(), cursors: HashMap::new(), - history: vec![], - } + history: Arc::new(RwLock::new(vec![])), + watcher, + _sending_map: Arc::new(RwLock::new(HashMap::new())), + }; + + Ok(chan) } } @@ -65,7 +87,13 @@ impl traits::Service for OT { let byte_contents = fs::read(path.clone()).await?; let crc32 = crc32fast::hash(byte_contents.as_slice()); - self.contents = String::from_utf8(byte_contents.clone())?.into(); + let mut _crc32 = self.crc32.write().await; + *_crc32 = crc32; + drop(_crc32); + + let mut contents = self.contents.write().await; + *contents = String::from_utf8(byte_contents.clone())?.into(); + drop(contents); let timestamp = Some(prost_types::Timestamp { seconds: SystemTime::now() @@ -75,9 +103,11 @@ impl traits::Service for OT { nanos: 0, }); + let version = self.version.read().await.clone(); + let hist_item = goval::OtPacket { - spooky_version: self.version, - version: self.version, + spooky_version: version, + version, op: vec![], crc32, committed: timestamp, @@ -86,20 +116,146 @@ impl traits::Service for OT { nonce: 0, }; - self.history.push(hist_item); + let mut history = self.history.write().await; + history.push(hist_item); + drop(history); let mut link_response = goval::Command::default(); let mut file = goval::File::default(); - file.path = path; + file.path = path.clone(); file.content = byte_contents; let _inner = goval::OtLinkFileResponse { - version: self.version, + version, linked_file: Some(file), }; link_response.body = Some(goval::command::Body::OtLinkFileResponse(_inner)); + self.watcher.watch(vec![path]).await?; + + let mut reader = self.watcher.get_event_reader().await; + let sending_map = self._sending_map.clone(); + let file_path = self.path.clone(); + let crc32 = self.crc32.clone(); + let contents = self.contents.clone(); + let version = self.version.clone(); + let history = self.history.clone(); + let channel_id = info.id.clone(); + tokio::spawn(async move { + loop { + let res = async { + match reader.recv().await { + Ok(res) => { + trace!(event = as_debug!(res.clone()), file_path = file_path; "oooh event"); + match res { + FSEvent::Modify(path) => { + trace!(condition = (path == file_path), path = path, file_path = file_path; "Conditional time"); + if path == file_path { + let new_contents = match fs::read(&path).await { + Ok(contents) => contents, + Err(err) => { + return LoopControl::Cont(Err(err.into())) + } + }; + + let new_crc32 = crc32fast::hash(&new_contents); + trace!("Awaiting crc32 lock"); + let old_crc32 = crc32.read().await; + if new_crc32 == old_crc32.clone() { + return LoopControl::Cont(Ok(())); + } + + drop(old_crc32); + + trace!("Awaiting contents lock"); + let mut old_contents = contents.write().await; + trace!("Awaiting version lock"); + let mut version = version.write().await; + *version += 1; + + let new_version = version.clone(); + let new_contents = String::from_utf8(new_contents) + .expect("TODO: Deal with this"); + + let ops = diff( + old_contents.to_string(), + new_contents.clone(), + ); + + *old_contents = new_contents.into(); + + let packet = goval::OtPacket { + spooky_version: new_version, + version: new_version, + op: ops, + committed: None, + crc32: new_crc32, + nonce: 0, + user_id: 0, + author: goval::ot_packet::Author::User.into(), + }; + + trace!("Awaiting history lock"); + let mut history = history.write().await; + history.push(packet.clone()); + + let mut ot_notif = goval::Command::default(); + ot_notif.channel = channel_id; + ot_notif.body = + Some(goval::command::Body::Ot(packet)); + + // info.send(ot_notif, crate::SendSessions::Everyone) + // .await + // .expect("TODO: Deal with this"); + + trace!("Awaiting sending lock"); + let to_send = sending_map.read().await; + + trace!("Sending..."); + for (session, sender) in to_send.iter() { + trace!(session = session; "Awaiting send"); + let mut msg = ot_notif.clone(); + msg.session = session.clone(); + + sender + .send(IPCMessage { + command: msg, + session: session.clone(), + }) + .expect("TODO: deal with this"); + trace!(session = session; "Sent"); + } + } + } + FSEvent::Err(err) => { + error!(error = err; "Error in FS event listener") + } + _ => { + debug!(message = as_debug!(res); "Ignoing FS event") + } + } + + LoopControl::Cont(Ok(())) + } + Err(err) => match err { + RecvError::Closed => LoopControl::Break, + RecvError::Lagged(ammount) => { + warn!(messages = ammount; "FSEvents lagged"); + LoopControl::Cont(Ok(())) + } + }, + } + } + .await; + + match res { + LoopControl::Break => break, + LoopControl::Cont(result) => result.expect("TODO: deal with this"), + } + } + }); + return Ok(Some(link_response)); } else { return Err(format_err!("Command sent before otLinkFile")); @@ -110,11 +266,12 @@ impl traits::Service for OT { goval::command::Body::Ot(ot) => { let mut cursor: usize = 0; + let mut contents = self.contents.write().await; for op in ot.op.clone() { match op.op_component.unwrap() { goval::ot_op_component::OpComponent::Skip(_skip) => { let skip: usize = _skip.try_into()?; - if skip + cursor > self.contents.len_chars() { + if skip + cursor > contents.len_chars() { let mut err = goval::Command::default(); err.body = Some(goval::command::Body::Error( "Invalid skip past bounds".to_string(), @@ -126,7 +283,7 @@ impl traits::Service for OT { } goval::ot_op_component::OpComponent::Delete(_delete) => { let delete: usize = _delete.try_into()?; - if delete + cursor > self.contents.len_chars() { + if delete + cursor > contents.len_chars() { let mut err = goval::Command::default(); err.body = Some(goval::command::Body::Error( "Invalid delete past bounds".to_string(), @@ -134,22 +291,25 @@ impl traits::Service for OT { return Ok(Some(err)); } - self.contents.remove(cursor..(cursor + delete)) + contents.remove(cursor..(cursor + delete)) } goval::ot_op_component::OpComponent::Insert(insert) => { - self.contents.insert(cursor, &insert) + contents.insert(cursor, &insert) } } } - let to_write = self.contents.to_string(); - self.version += 1; + let to_write = contents.to_string(); + let mut version = self.version.write().await; + *version += 1; + let saved_version = version.clone(); + drop(version); let user_id = 22261053; let crc32 = crc32fast::hash(to_write.as_bytes()); let packet = goval::OtPacket { - spooky_version: self.version, - version: self.version, + spooky_version: saved_version, + version: saved_version, op: ot.op, committed: None, crc32, @@ -158,7 +318,9 @@ impl traits::Service for OT { author: ot.author, }; - self.history.push(packet.clone()); + let mut history = self.history.write().await; + history.push(packet.clone()); + drop(history); let mut ot_notif = goval::Command::default(); ot_notif.body = Some(goval::command::Body::Ot(packet)); @@ -213,8 +375,13 @@ impl traits::Service for OT { &mut self, _info: &super::types::ChannelInfo, _client: ClientInfo, - _session: i32, + session: i32, + sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { + let mut sending_map = self._sending_map.write().await; + sending_map.insert(session, sender); + drop(sending_map); + if &self.path == "" { let mut cmd = goval::Command::default(); cmd.body = Some(goval::command::Body::Otstatus(goval::OtStatus::default())); @@ -232,8 +399,8 @@ impl traits::Service for OT { } let _inner = goval::OtStatus { - contents: self.contents.to_string(), - version: self.version, + contents: self.contents.read().await.to_string(), + version: self.version.read().await.clone(), linked_file: Some(file), cursors: cursors, }; @@ -241,4 +408,77 @@ impl traits::Service for OT { Ok(Some(status)) } + + async fn shutdown(self: Box, _info: &super::types::ChannelInfo) -> Result<()> { + self.watcher.shutdown().await; + Ok(()) + } +} + +fn diff(old_text: String, new_text: String) -> Vec { + let mut _differ = TextDiff::configure(); + let differ = _differ.timeout(Duration::from_secs(1)); + let diff = differ.diff_chars(&old_text, &new_text); + + let mut parts: Vec = vec![]; + let mut last_op: Option = None; + for part in diff.iter_all_changes() { + let mut new_op: Option = None; + match part.tag() { + similar::ChangeTag::Equal => { + if let Some(goval::ot_op_component::OpComponent::Skip(amount)) = last_op.clone() { + last_op = Some(goval::ot_op_component::OpComponent::Skip( + amount + part.value().len() as u32, + )) + } else { + new_op = Some(goval::ot_op_component::OpComponent::Skip( + part.value().len() as u32, + )); + } + } + similar::ChangeTag::Delete => { + if let Some(goval::ot_op_component::OpComponent::Delete(amount)) = last_op.clone() { + last_op = Some(goval::ot_op_component::OpComponent::Delete( + amount + part.value().len() as u32, + )) + } else { + new_op = Some(goval::ot_op_component::OpComponent::Delete( + part.value().len() as u32, + )); + } + } + similar::ChangeTag::Insert => { + if let Some(goval::ot_op_component::OpComponent::Insert(same)) = last_op.clone() { + last_op = Some(goval::ot_op_component::OpComponent::Insert( + same + part.value(), + )) + } else { + new_op = Some(goval::ot_op_component::OpComponent::Insert( + part.value().to_string(), + )); + } + } + } + + if let Some(new_part) = new_op { + if let Some(last_part) = last_op.clone() { + parts.push(goval::OtOpComponent { + op_component: Some(last_part), + }); + } + + last_op = Some(new_part); + } + } + + if let Some(op) = last_op { + match op { + goval::ot_op_component::OpComponent::Skip(_) => {} + _ => parts.push(goval::OtOpComponent { + op_component: Some(op), + }), + } + } + + parts } diff --git a/services/src/presence.rs b/services/src/presence.rs index f4f62bd..4d30416 100644 --- a/services/src/presence.rs +++ b/services/src/presence.rs @@ -2,7 +2,7 @@ pub struct Presence { users: Vec, files: HashMap, } -use crate::{ClientInfo, SendSessions}; +use crate::{ClientInfo, IPCMessage, SendSessions}; use log::{as_debug, info, warn}; use std::{ collections::HashMap, @@ -102,6 +102,7 @@ impl traits::Service for Presence { info: &super::types::ChannelInfo, client: ClientInfo, session: i32, + _sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { let mut roster = goval::Command::default(); let mut _inner = goval::Roster::default(); diff --git a/services/src/traits.rs b/services/src/traits.rs index 2c5c134..e667050 100644 --- a/services/src/traits.rs +++ b/services/src/traits.rs @@ -1,14 +1,14 @@ use anyhow::Result; use async_trait::async_trait; -use crate::ClientInfo; +use crate::{ClientInfo, IPCMessage}; #[async_trait] pub(crate) trait Service { async fn open(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { Ok(()) } - async fn shutdown(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { + async fn shutdown(self: Box, _info: &super::types::ChannelInfo) -> Result<()> { Ok(()) } @@ -26,6 +26,7 @@ pub(crate) trait Service { _info: &super::types::ChannelInfo, _client: ClientInfo, _session: i32, + _sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { Ok(None) } diff --git a/services/src/types.rs b/services/src/types.rs deleted file mode 100644 index 5752e0e..0000000 --- a/services/src/types.rs +++ /dev/null @@ -1,146 +0,0 @@ -use std::collections::HashMap; - -use anyhow::Result; -use goval; -use log::error; -use prost::Message; -use serde; -use serde::{Deserialize, Serialize}; -use tokio::sync::mpsc; - -pub enum SendSessions { - Only(i32), - EveryoneExcept(i32), - Everyone, -} - -pub struct ChannelInfo { - pub id: i32, - pub clients: HashMap>, - pub service: String, - pub name: Option, - pub sessions: HashMap, -} - -impl ChannelInfo { - pub async fn send(&self, mut message: goval::Command, sessions: SendSessions) -> Result<()> { - let clients: Vec; - message.channel = self.id; - match sessions { - SendSessions::Everyone => { - message.session = 0; - let mut _clients = vec![]; - for client in self.clients.keys() { - _clients.push(client.clone()) - } - - clients = _clients; - } - SendSessions::EveryoneExcept(excluded) => { - message.session = -excluded; - let mut _clients = vec![]; - for client in self.clients.keys() { - if client != &excluded { - _clients.push(client.clone()) - } - } - - clients = _clients; - } - SendSessions::Only(session) => { - message.session = session; - clients = vec![session] - } - } - - for client in clients { - if let Some(sender) = self.clients.get(&client) { - sender.send(IPCMessage { - command: message.clone(), - session: client, - })?; - } else { - error!("Missing session outbound message queue in op_send_msg") - } - } - Ok(()) - } -} - -#[derive(Clone)] -pub struct ServiceMetadata { - pub service: String, - pub name: Option, - pub id: i32, -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "camelCase")] -pub enum ReplspaceMessage { - GithubTokenReq(String), // nonce - OpenFileReq(String, bool, String), // file, wait for close, nonce - OpenMultipleFiles(Vec, String), // files, nonce - - GithubTokenRes(String), // token - OpenFileRes, -} - -#[derive(Clone, Debug)] -pub enum ChannelMessage { - IPC(IPCMessage), - Attach(i32, ClientInfo, mpsc::UnboundedSender), - Detach(i32), - ProcessDead(u32, i32), - CmdDead(i32), - Replspace(i32, ReplspaceMessage), // session, message - Shutdown, // Shutdown the service, value has to be true so that runtime.js can match it in an if check -} - -#[derive(Debug, Clone)] -pub struct IPCMessage { - pub command: goval::Command, - pub session: i32, -} - -impl IPCMessage { - pub fn replace_cmd(&self, cmd: goval::Command) -> IPCMessage { - IPCMessage { - command: cmd, - session: self.session, - } - } - - pub fn to_bytes(&self) -> Vec { - self.command.encode_to_vec() - } -} - -impl TryFrom> for IPCMessage { - type Error = anyhow::Error; - - fn try_from(value: Vec) -> Result { - Ok(Self { - command: goval::Command::decode(value.as_slice())?, - session: 0, - }) - } -} - -#[derive(Clone, Debug)] -pub struct ClientInfo { - pub is_secure: bool, - - pub username: String, - pub id: u32, -} - -impl Default for ClientInfo { - fn default() -> Self { - Self { - is_secure: false, - - username: "homeval-user".to_owned(), - id: 23054564, - } - } -} diff --git a/services/src/types/channel_info.rs b/services/src/types/channel_info.rs new file mode 100644 index 0000000..e97a9d3 --- /dev/null +++ b/services/src/types/channel_info.rs @@ -0,0 +1,67 @@ +use std::collections::HashMap; + +use anyhow::Result; +use goval; +use log::error; + +use super::client::ClientInfo; +use super::messaging::IPCMessage; + +pub enum SendSessions { + Only(i32), + EveryoneExcept(i32), + Everyone, +} + +pub struct ChannelInfo { + pub id: i32, + pub clients: HashMap>, + pub service: String, + pub name: Option, + pub sessions: HashMap, +} + +impl ChannelInfo { + pub async fn send(&self, mut message: goval::Command, sessions: SendSessions) -> Result<()> { + let clients: Vec; + message.channel = self.id; + match sessions { + SendSessions::Everyone => { + message.session = 0; + let mut _clients = vec![]; + for client in self.clients.keys() { + _clients.push(client.clone()) + } + + clients = _clients; + } + SendSessions::EveryoneExcept(excluded) => { + message.session = -excluded; + let mut _clients = vec![]; + for client in self.clients.keys() { + if client != &excluded { + _clients.push(client.clone()) + } + } + + clients = _clients; + } + SendSessions::Only(session) => { + message.session = session; + clients = vec![session] + } + } + + for client in clients { + if let Some(sender) = self.clients.get(&client) { + sender.send(IPCMessage { + command: message.clone(), + session: client, + })?; + } else { + error!("Missing session outbound message queue in op_send_msg") + } + } + Ok(()) + } +} diff --git a/services/src/types/client.rs b/services/src/types/client.rs new file mode 100644 index 0000000..bc71a2b --- /dev/null +++ b/services/src/types/client.rs @@ -0,0 +1,18 @@ +#[derive(Clone, Debug)] +pub struct ClientInfo { + pub is_secure: bool, + + pub username: String, + pub id: u32, +} + +impl Default for ClientInfo { + fn default() -> Self { + Self { + is_secure: false, + + username: "homeval-user".to_owned(), + id: 23054564, + } + } +} diff --git a/services/src/types/fs_watcher.rs b/services/src/types/fs_watcher.rs new file mode 100644 index 0000000..59e3148 --- /dev/null +++ b/services/src/types/fs_watcher.rs @@ -0,0 +1,136 @@ +use log::{as_debug, error}; +use notify_debouncer_full::{ + new_debouncer, + notify::{self, event::ModifyKind, Event, EventKind, RecommendedWatcher, Watcher}, + DebounceEventResult, Debouncer, +}; +use serde::Serialize; + +use anyhow::Result; + +use std::{path::Path, time::Duration}; +use tokio::sync::broadcast; + +// static FILE_WATCHER_MAP: LazyLock< +// RwLock>>>>, +// > = LazyLock::new(|| RwLock::new(HashMap::new())); +// static FILE_WATCHER_MESSAGES: LazyLock< +// RwLock>>>, +// > = LazyLock::new(|| RwLock::new(HashMap::new())); +// static MAX_WATCHER: LazyLock> = LazyLock::new(|| Mutex::new(0)); + +#[derive(Serialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub enum FSEvent { + Remove(String), + Create(String), + Modify(String), + Rename(String, String), + Err(String), +} + +pub struct FSWatcher { + debouncer: Debouncer, + writer: broadcast::Sender, + reader: broadcast::Receiver, +} + +impl FSWatcher { + pub async fn new() -> Result { + let (writer, reader) = broadcast::channel::(5); + + // FILE_WATCHER_MESSAGES + // .write() + // .await + // .insert(watcher_id, queue.clone()); + + // tokio::spawn(async move { + let debounce_writer = writer.clone(); + let debouncer = tokio::task::spawn_blocking(move || { + new_debouncer( + Duration::from_secs(1), + None, + move |result: DebounceEventResult| match result { + Ok(events) => events.iter().for_each(|event| { + if let Some(final_event) = notify_event_to_final(event).unwrap() { + debounce_writer + .send(final_event) + .expect("TODO: handle this"); + } + }), + Err(errors) => errors.iter().for_each(|error| { + error!(error = as_debug!(error); "Error in debouncer"); + debounce_writer + .send(FSEvent::Err(error.to_string())) + .expect("TODO: handle this"); + }), + }, + ) + + // let mut watcher_map = FILE_WATCHER_MAP.blocking_write(); + // watcher_map.insert(watcher_id, Arc::new(Mutex::new(debouncer))); + }) + .await??; + // }); + + Ok(FSWatcher { + debouncer, + reader, + writer, + }) + } + + pub async fn watch(&mut self, files: Vec) -> Result<()> { + for file in files { + let path = Path::new(&file); + self.debouncer + .watcher() + .watch(path, notify::RecursiveMode::NonRecursive)?; + self.debouncer + .cache() + .add_root(path, notify::RecursiveMode::NonRecursive) + } + + Ok(()) + } + + pub async fn shutdown(self) { + self.debouncer.stop_nonblocking(); + drop(self.writer) + } + + pub async fn get_event_reader(&mut self) -> broadcast::Receiver { + self.reader.resubscribe() + } +} + +fn notify_event_to_final(event: &Event) -> Result> { + let base = std::env::current_dir()?; + let file_name = event.paths[0] + .strip_prefix(base.clone())? + .to_str() + .unwrap() + .to_string(); + match event.kind { + EventKind::Create(_) => Ok(Some(FSEvent::Create(file_name))), + EventKind::Modify(_kind @ ModifyKind::Name(notify::event::RenameMode::Both)) => { + Ok(Some(FSEvent::Rename( + file_name, + event.paths[1] + .strip_prefix(base)? + .to_str() + .unwrap() + .to_string(), + ))) + } + EventKind::Modify(_kind @ ModifyKind::Name(notify::event::RenameMode::From)) => { + Ok(Some(FSEvent::Remove(file_name.to_string()))) + } + EventKind::Modify(_kind @ ModifyKind::Name(notify::event::RenameMode::To)) => { + Ok(Some(FSEvent::Create(file_name.to_string()))) + } + EventKind::Modify(_) => Ok(Some(FSEvent::Modify(file_name))), + EventKind::Remove(_) => Ok(Some(FSEvent::Remove(file_name))), + _ => Ok(None), + } +} diff --git a/services/src/types/messaging.rs b/services/src/types/messaging.rs new file mode 100644 index 0000000..b0da2c5 --- /dev/null +++ b/services/src/types/messaging.rs @@ -0,0 +1,63 @@ +use anyhow::Result; +use goval; +use prost::Message; +use serde; +use serde::{Deserialize, Serialize}; + +use super::client::ClientInfo; + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub enum ReplspaceMessage { + GithubTokenReq(String), // nonce + OpenFileReq(String, bool, String), // file, wait for close, nonce + OpenMultipleFiles(Vec, String), // files, nonce + + GithubTokenRes(String), // token + OpenFileRes, +} + +#[derive(Clone, Debug)] +pub enum ChannelMessage { + IPC(IPCMessage), + Attach( + i32, + ClientInfo, + tokio::sync::mpsc::UnboundedSender, + ), + Detach(i32), + ProcessDead(u32, i32), + CmdDead(i32), + Replspace(i32, ReplspaceMessage), // session, message + Shutdown, // Shutdown the service, value has to be true so that runtime.js can match it in an if check +} + +#[derive(Debug, Clone)] +pub struct IPCMessage { + pub command: goval::Command, + pub session: i32, +} + +impl IPCMessage { + pub fn replace_cmd(&self, cmd: goval::Command) -> IPCMessage { + IPCMessage { + command: cmd, + session: self.session, + } + } + + pub fn to_bytes(&self) -> Vec { + self.command.encode_to_vec() + } +} + +impl TryFrom> for IPCMessage { + type Error = anyhow::Error; + + fn try_from(value: Vec) -> Result { + Ok(Self { + command: goval::Command::decode(value.as_slice())?, + session: 0, + }) + } +} diff --git a/services/src/types/mod.rs b/services/src/types/mod.rs new file mode 100644 index 0000000..b5cce38 --- /dev/null +++ b/services/src/types/mod.rs @@ -0,0 +1,14 @@ +pub mod channel_info; +pub use channel_info::{ChannelInfo, SendSessions}; + +pub mod messaging; +pub use messaging::{ChannelMessage, IPCMessage, ReplspaceMessage}; + +pub mod client; +pub use client::ClientInfo; + +pub mod fs_watcher; +pub use fs_watcher::{FSEvent, FSWatcher}; + +pub mod service; +pub use service::ServiceMetadata; diff --git a/services/src/types/service.rs b/services/src/types/service.rs new file mode 100644 index 0000000..61950ff --- /dev/null +++ b/services/src/types/service.rs @@ -0,0 +1,6 @@ +#[derive(Clone, Debug)] +pub struct ServiceMetadata { + pub service: String, + pub name: Option, + pub id: i32, +} diff --git a/src/goval_server.rs b/src/goval_server.rs index af1c5da..0569330 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -276,8 +276,9 @@ async fn open_channel( trace!(channel = channel_id_held; "Added channel to queue list"); tokio::spawn(async move { - let mut channel = - homeval_services::Channel::new(channel_id, service, _channel_name).unwrap(); + let channel = homeval_services::Channel::new(channel_id, service, _channel_name) + .await + .expect("TODO: Deal with this"); channel.start(reader).await; }); found = true; From e3bbedb09cb1768c90c136485c9157ed30051c50 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 26 Jun 2023 18:58:30 -0700 Subject: [PATCH 008/103] feat(services): Implement viewable history for ot service --- Cargo.toml | 2 +- services/src/ot.rs | 70 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4195ddd..c371a9b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,7 @@ log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } prost = "0.11.8" prost-types = "0.11.8" serde_json = "1.0.97" -serde = "1.0.162" +serde = { version = "1.0.162", features = ["derive"] } tokio = {version="1.26.0", features = ["full"]} base64 = "0.21.0" futures = "0.3.28" diff --git a/services/src/ot.rs b/services/src/ot.rs index 69533f0..4281ddd 100644 --- a/services/src/ot.rs +++ b/services/src/ot.rs @@ -91,8 +91,10 @@ impl traits::Service for OT { *_crc32 = crc32; drop(_crc32); + let file_contents = String::from_utf8(byte_contents.clone())?; + let mut contents = self.contents.write().await; - *contents = String::from_utf8(byte_contents.clone())?.into(); + *contents = file_contents.clone().into(); drop(contents); let timestamp = Some(prost_types::Timestamp { @@ -108,7 +110,13 @@ impl traits::Service for OT { let hist_item = goval::OtPacket { spooky_version: version, version, - op: vec![], + op: vec![ + goval::OtOpComponent { + op_component: Some( + goval::ot_op_component::OpComponent::Insert(file_contents) + ) + } + ], crc32, committed: timestamp, author: goval::ot_packet::Author::User.into(), @@ -185,11 +193,19 @@ impl traits::Service for OT { *old_contents = new_contents.into(); + let committed = Some(prost_types::Timestamp { + seconds: SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() as i64, + nanos: 0, + }); + let packet = goval::OtPacket { spooky_version: new_version, version: new_version, op: ops, - committed: None, + committed, crc32: new_crc32, nonce: 0, user_id: 0, @@ -303,15 +319,36 @@ impl traits::Service for OT { let mut version = self.version.write().await; *version += 1; let saved_version = version.clone(); - drop(version); - let user_id = 22261053; + // drop(version); + + let user_id; + if ot.author == goval::ot_packet::Author::Ghostwriter as i32 { + user_id = 22261053 // https://replit.com/@ghostwriterai + } else { + if let Some(user) = info.sessions.get(&session) { + user_id = user.id.clone() + } else { + user_id = 23054564 // https://replit.com/@homeval-user + } + } + let crc32 = crc32fast::hash(to_write.as_bytes()); + let mut _crc32 = self.crc32.write().await; + *_crc32 = crc32; + + let committed = Some(prost_types::Timestamp { + seconds: SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() as i64, + nanos: 0, + }); let packet = goval::OtPacket { spooky_version: saved_version, version: saved_version, op: ot.op, - committed: None, + committed, crc32, nonce: 0, user_id, @@ -320,7 +357,7 @@ impl traits::Service for OT { let mut history = self.history.write().await; history.push(packet.clone()); - drop(history); + // drop(history); let mut ot_notif = goval::Command::default(); ot_notif.body = Some(goval::command::Body::Ot(packet)); @@ -359,6 +396,25 @@ impl traits::Service for OT { Ok(None) } + goval::command::Body::OtFetchRequest(request) => { + let mut packets: Vec = vec![]; + let from = (request.version_from - 1) as usize; + let to = request.version_to as usize; + let history = self.history.read().await; + for (index, item) in history.iter().enumerate() { + if index >= from && index <= to { + packets.push(item.clone()) + } + } + + let mut history_result = goval::Command::default(); + let _inner = goval::OtFetchResponse { + packets + }; + history_result.body = Some(goval::command::Body::OtFetchResponse(_inner)); + + Ok(Some(history_result)) + } goval::command::Body::Flush(_) => { let mut ok = goval::Command::default(); ok.body = Some(goval::command::Body::Ok(goval::Ok {})); From 055a05221e1bb158d539d2af627c3e892bd842d7 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 26 Jun 2023 19:00:39 -0700 Subject: [PATCH 009/103] feat(services): Add stubs for null, open, and git * `null` - doesn't do anything anyways * `git` - the client only sends messages after recieving one from the server * `open` - client doesn't seem to ever send it messages --- services/src/lib.rs | 7 ++++++- services/src/stub.rs | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 services/src/stub.rs diff --git a/services/src/lib.rs b/services/src/lib.rs index f2dad3e..635a578 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -2,6 +2,7 @@ mod chat; mod gcsfiles; mod ot; mod presence; +mod stub; mod traits; mod types; @@ -25,6 +26,9 @@ impl Channel { "gcsfiles" => Box::new(gcsfiles::GCSFiles {}), "presence" => Box::new(presence::Presence::new()), "ot" => Box::new(ot::OT::new().await?), + "null" => Box::new(stub::Stub {}), // This channel never does anything + "open" => Box::new(stub::Stub {}), // Stub until infra is set up to handle this + "git" => Box::new(stub::Stub {}), // Stub until replspace api is fixed _ => return Err(format_err!("Unknown service: {}", service)), }; @@ -118,4 +122,5 @@ impl Channel { } } -pub static IMPLEMENTED_SERVICES: &[&str] = &["chat", "gcsfiles", "presence", "ot"]; +pub static IMPLEMENTED_SERVICES: &[&str] = + &["chat", "gcsfiles", "presence", "ot", "null", "git", "open"]; diff --git a/services/src/stub.rs b/services/src/stub.rs new file mode 100644 index 0000000..b19fdc2 --- /dev/null +++ b/services/src/stub.rs @@ -0,0 +1,4 @@ +pub struct Stub {} +use super::traits; + +impl traits::Service for Stub {} From 7b9e015e6da93f3106e2cad2dfd82cd184a3cc7d Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 26 Jun 2023 19:50:20 -0700 Subject: [PATCH 010/103] feat(services): Pure rust snapshot implementation --- services/src/lib.rs | 7 +++++-- services/src/snapshot.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 services/src/snapshot.rs diff --git a/services/src/lib.rs b/services/src/lib.rs index 635a578..8d93951 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -2,6 +2,7 @@ mod chat; mod gcsfiles; mod ot; mod presence; +mod snapshot; mod stub; mod traits; mod types; @@ -26,6 +27,7 @@ impl Channel { "gcsfiles" => Box::new(gcsfiles::GCSFiles {}), "presence" => Box::new(presence::Presence::new()), "ot" => Box::new(ot::OT::new().await?), + "snapshot" => Box::new(snapshot::Snapshot {}), "null" => Box::new(stub::Stub {}), // This channel never does anything "open" => Box::new(stub::Stub {}), // Stub until infra is set up to handle this "git" => Box::new(stub::Stub {}), // Stub until replspace api is fixed @@ -122,5 +124,6 @@ impl Channel { } } -pub static IMPLEMENTED_SERVICES: &[&str] = - &["chat", "gcsfiles", "presence", "ot", "null", "git", "open"]; +pub static IMPLEMENTED_SERVICES: &[&str] = &[ + "chat", "gcsfiles", "presence", "ot", "snapshot", "null", "git", "open", +]; diff --git a/services/src/snapshot.rs b/services/src/snapshot.rs new file mode 100644 index 0000000..0806a21 --- /dev/null +++ b/services/src/snapshot.rs @@ -0,0 +1,29 @@ +pub struct Snapshot {} + +use super::traits; +use anyhow::{format_err, Result}; +use async_trait::async_trait; + +#[async_trait] +impl traits::Service for Snapshot { + async fn message( + &mut self, + _info: &super::types::ChannelInfo, + message: goval::Command, + _session: i32, + ) -> Result> { + let body = match message.body.clone() { + None => return Err(format_err!("Expected command body")), + Some(body) => body, + }; + + match body { + goval::command::Body::FsSnapshot(_) => { + let mut ok = goval::Command::default(); + ok.body = Some(goval::command::Body::Ok(goval::Ok {})); + Ok(Some(ok)) + } + _ => Ok(None), + } + } +} From 3cfea7f9daf5ab2289121bb2400e09349ec79c32 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Tue, 27 Jun 2023 15:24:54 -0700 Subject: [PATCH 011/103] build(deps): Update deps --- Cargo.lock | 166 +++++++++++++++++++++++++++++------------------------ 1 file changed, 91 insertions(+), 75 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fea9a57..66f9eb6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,7 +97,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", ] [[package]] @@ -108,7 +108,7 @@ checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", ] [[package]] @@ -389,7 +389,7 @@ dependencies = [ "bitflags", "clap_derive", "clap_lex", - "indexmap", + "indexmap 1.9.3", "once_cell", "textwrap", ] @@ -587,6 +587,12 @@ dependencies = [ "termcolor", ] +[[package]] +name = "equivalent" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" + [[package]] name = "erased-serde" version = "0.3.25" @@ -777,7 +783,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", ] [[package]] @@ -846,9 +852,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" +checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" dependencies = [ "bytes", "fnv", @@ -856,7 +862,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 1.9.3", "slab", "tokio", "tokio-util", @@ -988,7 +994,7 @@ dependencies = [ "services", "textnonce", "tokio", - "toml 0.7.4", + "toml 0.7.5", ] [[package]] @@ -1033,9 +1039,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" dependencies = [ "bytes", "futures-channel", @@ -1111,6 +1117,16 @@ dependencies = [ "hashbrown 0.12.3", ] +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown 0.14.0", +] + [[package]] name = "inotify" version = "0.9.6" @@ -1215,9 +1231,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.146" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "linux-raw-sys" @@ -1419,9 +1435,9 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.54" +version = "0.10.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" +checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" dependencies = [ "bitflags", "cfg-if", @@ -1440,7 +1456,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", ] [[package]] @@ -1451,9 +1467,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.88" +version = "0.9.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2ce0f250f34a308dcfdbb351f511359857d4ed2134ba715a4eadd46e1ffd617" +checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" dependencies = [ "cc", "libc", @@ -1591,23 +1607,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" dependencies = [ "fixedbitset", - "indexmap", + "indexmap 1.9.3", ] [[package]] name = "phf" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ "phf_shared", ] [[package]] name = "phf_codegen" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56ac890c5e3ca598bbdeaa99964edb5b0258a583a9eb6ef4e89fc85d9224770" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" dependencies = [ "phf_generator", "phf_shared", @@ -1615,9 +1631,9 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" dependencies = [ "phf_shared", "rand 0.8.5", @@ -1625,9 +1641,9 @@ dependencies = [ [[package]] name = "phf_shared" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1fb5f6f826b772a8d4c0394209441e7d37cbbb967ae9c7e0e8134365c9ee676" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" dependencies = [ "siphasher", ] @@ -1649,7 +1665,7 @@ checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", ] [[package]] @@ -1721,9 +1737,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" dependencies = [ "unicode-ident", ] @@ -2328,7 +2344,7 @@ checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", ] [[package]] @@ -2342,9 +2358,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.97" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf3bf93142acad5821c99197022e170842cdbc1c30482b98750c688c640842a" +checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" dependencies = [ "itoa", "ryu", @@ -2362,9 +2378,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93107647184f6027e3b7dcb2e11034cf95ffa1e3a682c67951963ac69c1c007d" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" dependencies = [ "serde", ] @@ -2538,7 +2554,7 @@ dependencies = [ "hex", "hkdf", "hmac", - "indexmap", + "indexmap 1.9.3", "itoa", "libc", "log", @@ -2623,15 +2639,15 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "sval" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2faba619276044eec7cd160d87b15d9191fb9b9f7198440343d2144f760cf08" +checksum = "8b031320a434d3e9477ccf9b5756d57d4272937b8d22cb88af80b7633a1b78b1" [[package]] name = "sval_buffer" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a353d3cca10721384077c9643c3fafdd6ed2600e57933b8e45c0b580d97b25af" +checksum = "6bf7e9412af26b342f3f2cc5cc4122b0105e9d16eb76046cd14ed10106cf6028" dependencies = [ "sval", "sval_ref", @@ -2639,18 +2655,18 @@ dependencies = [ [[package]] name = "sval_dynamic" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee5fc7349e9f6cb2ab950046818f66ad3f2d7209ccc5dced93da19292a30273a" +checksum = "a0ef628e8a77a46ed3338db8d1b08af77495123cc229453084e47cd716d403cf" dependencies = [ "sval", ] [[package]] name = "sval_fmt" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "098fb51d5d6007bd2c3f0a23b79aa953d7c46bf943086ce51424c3187c40f9b1" +checksum = "7dc09e9364c2045ab5fa38f7b04d077b3359d30c4c2b3ec4bae67a358bd64326" dependencies = [ "itoa", "ryu", @@ -2659,9 +2675,9 @@ dependencies = [ [[package]] name = "sval_json" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f01126a2783d767496f18f13af26ab2587881f6343368bb26dc62956a723d1c7" +checksum = "ada6f627e38cbb8860283649509d87bc4a5771141daa41c78fd31f2b9485888d" dependencies = [ "itoa", "ryu", @@ -2670,18 +2686,18 @@ dependencies = [ [[package]] name = "sval_ref" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5854d9eaa7bd31840a850322591c59c5b547eb29c9a6ecee1989d6ef963312ce" +checksum = "703ca1942a984bd0d9b5a4c0a65ab8b4b794038d080af4eb303c71bc6bf22d7c" dependencies = [ "sval", ] [[package]] name = "sval_serde" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cdd25fc04c5e882787d62112591aa93efb5bdc2000b43164d29f08582bb85f7" +checksum = "830926cd0581f7c3e5d51efae4d35c6b6fc4db583842652891ba2f1bed8db046" dependencies = [ "serde", "sval", @@ -2702,9 +2718,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.18" +version = "2.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" dependencies = [ "proc-macro2", "quote", @@ -2779,7 +2795,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", ] [[package]] @@ -2872,7 +2888,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", ] [[package]] @@ -2944,9 +2960,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6135d499e69981f9ff0ef2167955a5333c35e36f6937d382974566b3d5b94ec" +checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240" dependencies = [ "serde", "serde_spanned", @@ -2956,20 +2972,20 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.19.10" +version = "0.19.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" +checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7" dependencies = [ - "indexmap", + "indexmap 2.0.0", "serde", "serde_spanned", "toml_datetime", @@ -3019,13 +3035,13 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8803eee176538f94ae9a14b55b2804eb7e1441f8210b1c31290b3bccdccff73b" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", ] [[package]] @@ -3141,18 +3157,18 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "uuid" -version = "1.3.4" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81" +checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" dependencies = [ "serde", ] [[package]] name = "value-bag" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4d330786735ea358f3bc09eea4caa098569c1c93f342d9aca0514915022fe7e" +checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" dependencies = [ "value-bag-serde1", "value-bag-sval2", @@ -3160,9 +3176,9 @@ dependencies = [ [[package]] name = "value-bag-serde1" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4735c95b4cca1447b448e2e2e87e98d7e7498f4da27e355cf7af02204521001d" +checksum = "b0b9f3feef403a50d4d67e9741a6d8fc688bcbb4e4f31bd4aab72cc690284394" dependencies = [ "erased-serde", "serde", @@ -3171,9 +3187,9 @@ dependencies = [ [[package]] name = "value-bag-sval2" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859cb4f0ce7da6a118b559ba74b0e63bf569bea867c20ba457a6b1c886a04e97" +checksum = "30b24f4146b6f3361e91cbf527d1fb35e9376c3c0cef72ca5ec5af6d640fad7d" dependencies = [ "sval", "sval_buffer", @@ -3254,7 +3270,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", "wasm-bindgen-shared", ] @@ -3276,7 +3292,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.22", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3329,9 +3345,9 @@ dependencies = [ [[package]] name = "whoami" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c70234412ca409cc04e864e89523cb0fc37f5e1344ebed5a3ebf4192b6b9f68" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" dependencies = [ "wasm-bindgen", "web-sys", From ec15d765c9447bf0919761527eb79a75a4df9bc7 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Tue, 27 Jun 2023 15:25:22 -0700 Subject: [PATCH 012/103] build: Temporarily disable all optional features by default --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index c371a9b..6199e84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ See https://govaldocs.pages.dev""" members = [".", "migration", "entity", "services", "protobuf"] [features] -default = ["replspace", "database", "repldb", "verify_connections"] +default = [] #"replspace", "database", "repldb", "verify_connections"] repldb = ["database"] database = ["dep:sea-orm", "dep:sea-query", "dep:migration", "dep:entity"] replspace = [] From f6b3c513194853e6060a72b181ce980f9c0b96e3 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Tue, 27 Jun 2023 15:25:44 -0700 Subject: [PATCH 013/103] feat(services): Implement chat scrollback --- services/src/chat.rs | 58 +++++++++++++++++++++++++++++++++++++++----- services/src/lib.rs | 2 +- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/services/src/chat.rs b/services/src/chat.rs index 9584323..728063f 100644 --- a/services/src/chat.rs +++ b/services/src/chat.rs @@ -1,9 +1,19 @@ -pub struct Chat {} -use crate::{ClientInfo, SendSessions}; +pub struct Chat { + history: Vec, +} + +use crate::{ClientInfo, IPCMessage, SendSessions}; use super::traits; -use anyhow::Result; +use anyhow::{format_err, Result}; use async_trait::async_trait; +use log::{as_debug, warn}; + +impl Chat { + pub fn new() -> Chat { + Chat { history: vec![] } + } +} #[async_trait] impl traits::Service for Chat { @@ -17,8 +27,44 @@ impl traits::Service for Chat { message: goval::Command, session: i32, ) -> Result> { - info.send(message, SendSessions::EveryoneExcept(session)) - .await?; - Ok(None) + let body = match message.body.clone() { + None => return Err(format_err!("Expected command body")), + Some(body) => body, + }; + + match body { + goval::command::Body::ChatMessage(msg) => { + info.send(message, SendSessions::EveryoneExcept(session)) + .await?; + self.history.push(msg); + Ok(None) + } + goval::command::Body::ChatTyping(_) => { + info.send(message, SendSessions::EveryoneExcept(session)) + .await?; + Ok(None) + } + _ => { + warn!(cmd = as_debug!(message); "Unknown chat command"); + Ok(None) + } + } + } + + async fn attach( + &mut self, + _info: &super::types::ChannelInfo, + _client: ClientInfo, + _session: i32, + _sender: tokio::sync::mpsc::UnboundedSender, + ) -> Result> { + let mut scrollback = goval::Command::default(); + let _inner = goval::ChatScrollback { + scrollback: self.history.clone(), + }; + + scrollback.body = Some(goval::command::Body::ChatScrollback(_inner)); + + Ok(Some(scrollback)) } } diff --git a/services/src/lib.rs b/services/src/lib.rs index 8d93951..2ac042f 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -23,7 +23,7 @@ pub struct Channel { impl Channel { pub async fn new(id: i32, service: String, name: Option) -> Result { let channel: Box = match service.as_str() { - "chat" => Box::new(chat::Chat {}), + "chat" => Box::new(chat::Chat::new()), "gcsfiles" => Box::new(gcsfiles::GCSFiles {}), "presence" => Box::new(presence::Presence::new()), "ot" => Box::new(ot::OT::new().await?), From 56823692072b6484e1b672dc136104de0dc1953f Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Tue, 27 Jun 2023 15:26:17 -0700 Subject: [PATCH 014/103] feat(services): Add placeholder for .env in db code --- services/src/gcsfiles.rs | 47 +++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/services/src/gcsfiles.rs b/services/src/gcsfiles.rs index bd3f2ac..a43bb8e 100644 --- a/services/src/gcsfiles.rs +++ b/services/src/gcsfiles.rs @@ -3,7 +3,7 @@ pub struct GCSFiles {} use super::traits; use anyhow::{format_err, Result}; use async_trait::async_trait; -use log::{as_debug, as_error, warn}; +use log::{as_debug, as_error, debug, warn}; use tokio::{fs, io::AsyncWriteExt}; #[async_trait] @@ -57,22 +57,25 @@ impl traits::Service for GCSFiles { Ok(Some(ret)) } goval::command::Body::Read(file) => { - let contents; - if file.path == ".config/goval/info" { - let val = serde_json::json!({ - "server": "homeval", - "version": env!("CARGO_PKG_VERSION").to_string(), - "license": "AGPL", - "authors": vec!["PotentialStyx <62217716+PotentialStyx@users.noreply.github.com>"], - "repository": "https://github.com/goval-community/homeval", - "description": "", // TODO: do dis - "uptime": 0, // TODO: impl fo realz - "services": super::IMPLEMENTED_SERVICES.clone() - }); + debug!(path = file.path; "File path"); + let contents = match file.path.as_str() { + // TODO: Read this from in the db + ".env" => vec![], + ".config/goval/info" => { + let val = serde_json::json!({ + "server": "homeval", + "version": env!("CARGO_PKG_VERSION").to_string(), + "license": "AGPL", + "authors": vec!["PotentialStyx <62217716+PotentialStyx@users.noreply.github.com>"], + "repository": "https://github.com/goval-community/homeval", + "description": "", // TODO: do dis + "uptime": 0, // TODO: impl fo realz + "services": super::IMPLEMENTED_SERVICES.clone() + }); - contents = val.to_string().as_bytes().to_vec(); - } else { - contents = match fs::read(&file.path).await { + val.to_string().as_bytes().to_vec() + } + _ => match fs::read(&file.path).await { Err(err) => { warn!(error = as_error!(err); "Error reading file in gcsfiles"); let mut ret = goval::Command::default(); @@ -84,8 +87,9 @@ impl traits::Service for GCSFiles { return Ok(Some(ret)); } Ok(contents) => contents, - } - } + }, + }; + let mut ret = goval::Command::default(); let mut _inner = goval::File::default(); _inner.content = contents; @@ -112,6 +116,13 @@ impl traits::Service for GCSFiles { Ok(Some(ret)) } goval::command::Body::Write(_file) => { + // TODO: Store this in the db + if &_file.path == ".env" { + let mut ret = goval::Command::default(); + ret.body = Some(goval::command::Body::Ok(goval::Ok {})); + return Ok(Some(ret)); + } + let mut file = fs::OpenOptions::new() .write(true) .create(true) From 842bc43009421e5b5b5480184efc37ee0c9cf221 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 7 Oct 2023 18:29:53 -0700 Subject: [PATCH 015/103] feat: lockless OT --- Cargo.lock | 148 +++++++++++++ services/Cargo.toml | 2 + services/src/lib.rs | 11 +- services/src/ot.rs | 333 ++++++++++++---------------- services/src/traits.rs | 6 +- services/src/types/channel_info.rs | 1 + services/src/types/fs_watcher.rs | 25 +-- services/src/types/messaging.rs | 1 + services/src/types/mod.rs | 2 + services/src/types/pty.rs | 344 +++++++++++++++++++++++++++++ src/goval_server.rs | 9 +- 11 files changed, 663 insertions(+), 219 deletions(-) create mode 100644 services/src/types/pty.rs diff --git a/Cargo.lock b/Cargo.lock index 66f9eb6..213e1f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -552,6 +552,12 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + [[package]] name = "ed25519-compact" version = "2.0.4" @@ -653,6 +659,17 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "filedescriptor" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7199d965852c3bac31f779ef99cbb4537f80e952e2d6aa0ffeb30cce00f4f46e" +dependencies = [ + "libc", + "thiserror", + "winapi", +] + [[package]] name = "filetime" version = "0.2.21" @@ -1167,6 +1184,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "ioctl-rs" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7970510895cee30b3e9128319f2cefd4bde883a39f38baa279567ba3a7eb97d" +dependencies = [ + "libc", +] + [[package]] name = "is-terminal" version = "0.4.7" @@ -1291,6 +1317,15 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "migration" version = "0.1.0" @@ -1347,6 +1382,20 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nix" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "libc", + "memoffset", + "pin-utils", +] + [[package]] name = "nom" version = "7.1.3" @@ -1686,6 +1735,27 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "portable-pty" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "806ee80c2a03dbe1a9fb9534f8d19e4c0546b790cde8fd1fea9d6390644cb0be" +dependencies = [ + "anyhow", + "bitflags", + "downcast-rs", + "filedescriptor", + "lazy_static", + "libc", + "log", + "nix", + "serial", + "shared_library", + "shell-words", + "winapi", + "winreg", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2397,6 +2467,48 @@ dependencies = [ "serde", ] +[[package]] +name = "serial" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1237a96570fc377c13baa1b88c7589ab66edced652e43ffb17088f003db3e86" +dependencies = [ + "serial-core", + "serial-unix", + "serial-windows", +] + +[[package]] +name = "serial-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f46209b345401737ae2125fe5b19a77acce90cd53e1658cda928e4fe9a64581" +dependencies = [ + "libc", +] + +[[package]] +name = "serial-unix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f03fbca4c9d866e24a459cbca71283f545a37f8e3e002ad8c70593871453cab7" +dependencies = [ + "ioctl-rs", + "libc", + "serial-core", + "termios", +] + +[[package]] +name = "serial-windows" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c6d3b776267a75d31bbdfd5d36c0ca051251caafc285827052bc53bcdc8162" +dependencies = [ + "libc", + "serial-core", +] + [[package]] name = "services" version = "0.1.0" @@ -2405,8 +2517,10 @@ dependencies = [ "async-trait", "crc32fast", "deadqueue", + "futures-util", "log", "notify-debouncer-full", + "portable-pty", "prost", "prost-types", "protobuf", @@ -2448,6 +2562,22 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shared_library" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -2762,6 +2892,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "termios" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d9cf598a6d7ce700a4e6a9199da127e6819a61e64b68609683cc9a01b5683a" +dependencies = [ + "libc", +] + [[package]] name = "textnonce" version = "1.0.0" @@ -3549,6 +3688,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] + [[package]] name = "wyz" version = "0.5.1" diff --git a/services/Cargo.toml b/services/Cargo.toml index b85fabe..f98f524 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -10,9 +10,11 @@ anyhow = "1.0.71" async-trait = "0.1.68" crc32fast = { version = "1.3.2", features = ["nightly"] } deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } +futures-util = "0.3.28" goval = { package = "protobuf", path = "../protobuf"} log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } notify-debouncer-full = { version = "0.2.0", default-features = false } +portable-pty = "0.8.1" prost = "0.11.9" prost-types = "0.11.9" ropey = "1.6.0" diff --git a/services/src/lib.rs b/services/src/lib.rs index 2ac042f..f74c7be 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -21,12 +21,17 @@ pub struct Channel { // Public functions impl Channel { - pub async fn new(id: i32, service: String, name: Option) -> Result { + pub async fn new( + id: i32, + service: String, + name: Option, + sender: tokio::sync::mpsc::UnboundedSender, + ) -> Result { let channel: Box = match service.as_str() { "chat" => Box::new(chat::Chat::new()), "gcsfiles" => Box::new(gcsfiles::GCSFiles {}), "presence" => Box::new(presence::Presence::new()), - "ot" => Box::new(ot::OT::new().await?), + "ot" => Box::new(ot::OT::new(sender.clone()).await?), "snapshot" => Box::new(snapshot::Snapshot {}), "null" => Box::new(stub::Stub {}), // This channel never does anything "open" => Box::new(stub::Stub {}), // Stub until infra is set up to handle this @@ -40,6 +45,7 @@ impl Channel { service, clients: HashMap::new(), sessions: HashMap::new(), + sender, }; Ok(Channel { @@ -66,6 +72,7 @@ impl Channel { break; } }, + ChannelMessage::FSEvent(event) => self._inner.fsevent(&self.info, event).await, }; match result { diff --git a/services/src/ot.rs b/services/src/ot.rs index 4281ddd..98cd1f4 100644 --- a/services/src/ot.rs +++ b/services/src/ot.rs @@ -1,17 +1,15 @@ pub struct OT { - crc32: Arc>, - version: Arc>, - contents: Arc>, + crc32: u32, + version: u32, + contents: ropey::Rope, path: String, cursors: HashMap, - history: Arc>>, + history: Vec, watcher: FSWatcher, - _sending_map: Arc>>>, } use std::{ collections::HashMap, - sync::Arc, time::{Duration, SystemTime, UNIX_EPOCH}, }; @@ -20,12 +18,9 @@ use crate::{client::ClientInfo, fs_watcher::FSWatcher, FSEvent, IPCMessage}; use super::traits; use anyhow::{format_err, Result}; use async_trait::async_trait; -use log::{as_debug, debug, error, warn, trace}; +use log::{as_debug, debug, error, trace, warn}; use similar::TextDiff; -use tokio::{ - fs, - sync::{broadcast::error::RecvError, RwLock}, -}; +use tokio::fs; enum LoopControl { Cont(Result<()>), @@ -33,18 +28,19 @@ enum LoopControl { } impl OT { - pub async fn new() -> Result { - let watcher = FSWatcher::new().await?; + pub async fn new( + sender: tokio::sync::mpsc::UnboundedSender, + ) -> Result { + let watcher = FSWatcher::new(sender).await?; let chan = OT { - crc32: Arc::new(RwLock::new(0)), - version: Arc::new(RwLock::new(1)), - contents: Arc::new(RwLock::new("".into())), + crc32: 0, + version: 1, + contents: "".into(), path: "".to_string(), cursors: HashMap::new(), - history: Arc::new(RwLock::new(vec![])), + history: vec![], watcher, - _sending_map: Arc::new(RwLock::new(HashMap::new())), }; Ok(chan) @@ -87,15 +83,11 @@ impl traits::Service for OT { let byte_contents = fs::read(path.clone()).await?; let crc32 = crc32fast::hash(byte_contents.as_slice()); - let mut _crc32 = self.crc32.write().await; - *_crc32 = crc32; - drop(_crc32); + self.crc32 = crc32; let file_contents = String::from_utf8(byte_contents.clone())?; - let mut contents = self.contents.write().await; - *contents = file_contents.clone().into(); - drop(contents); + self.contents = file_contents.clone().into(); let timestamp = Some(prost_types::Timestamp { seconds: SystemTime::now() @@ -105,18 +97,14 @@ impl traits::Service for OT { nanos: 0, }); - let version = self.version.read().await.clone(); - let hist_item = goval::OtPacket { - spooky_version: version, - version, - op: vec![ - goval::OtOpComponent { - op_component: Some( - goval::ot_op_component::OpComponent::Insert(file_contents) - ) - } - ], + spooky_version: self.version, + version: self.version, + op: vec![goval::OtOpComponent { + op_component: Some(goval::ot_op_component::OpComponent::Insert( + file_contents, + )), + }], crc32, committed: timestamp, author: goval::ot_packet::Author::User.into(), @@ -124,9 +112,7 @@ impl traits::Service for OT { nonce: 0, }; - let mut history = self.history.write().await; - history.push(hist_item); - drop(history); + self.history.push(hist_item); let mut link_response = goval::Command::default(); @@ -135,142 +121,46 @@ impl traits::Service for OT { file.content = byte_contents; let _inner = goval::OtLinkFileResponse { - version, + version: self.version, linked_file: Some(file), }; link_response.body = Some(goval::command::Body::OtLinkFileResponse(_inner)); self.watcher.watch(vec![path]).await?; - let mut reader = self.watcher.get_event_reader().await; - let sending_map = self._sending_map.clone(); - let file_path = self.path.clone(); - let crc32 = self.crc32.clone(); - let contents = self.contents.clone(); - let version = self.version.clone(); - let history = self.history.clone(); - let channel_id = info.id.clone(); - tokio::spawn(async move { - loop { - let res = async { - match reader.recv().await { - Ok(res) => { - trace!(event = as_debug!(res.clone()), file_path = file_path; "oooh event"); - match res { - FSEvent::Modify(path) => { - trace!(condition = (path == file_path), path = path, file_path = file_path; "Conditional time"); - if path == file_path { - let new_contents = match fs::read(&path).await { - Ok(contents) => contents, - Err(err) => { - return LoopControl::Cont(Err(err.into())) - } - }; - - let new_crc32 = crc32fast::hash(&new_contents); - trace!("Awaiting crc32 lock"); - let old_crc32 = crc32.read().await; - if new_crc32 == old_crc32.clone() { - return LoopControl::Cont(Ok(())); - } - - drop(old_crc32); - - trace!("Awaiting contents lock"); - let mut old_contents = contents.write().await; - trace!("Awaiting version lock"); - let mut version = version.write().await; - *version += 1; - - let new_version = version.clone(); - let new_contents = String::from_utf8(new_contents) - .expect("TODO: Deal with this"); - - let ops = diff( - old_contents.to_string(), - new_contents.clone(), - ); - - *old_contents = new_contents.into(); - - let committed = Some(prost_types::Timestamp { - seconds: SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs() as i64, - nanos: 0, - }); - - let packet = goval::OtPacket { - spooky_version: new_version, - version: new_version, - op: ops, - committed, - crc32: new_crc32, - nonce: 0, - user_id: 0, - author: goval::ot_packet::Author::User.into(), - }; - - trace!("Awaiting history lock"); - let mut history = history.write().await; - history.push(packet.clone()); - - let mut ot_notif = goval::Command::default(); - ot_notif.channel = channel_id; - ot_notif.body = - Some(goval::command::Body::Ot(packet)); - - // info.send(ot_notif, crate::SendSessions::Everyone) - // .await - // .expect("TODO: Deal with this"); - - trace!("Awaiting sending lock"); - let to_send = sending_map.read().await; - - trace!("Sending..."); - for (session, sender) in to_send.iter() { - trace!(session = session; "Awaiting send"); - let mut msg = ot_notif.clone(); - msg.session = session.clone(); - - sender - .send(IPCMessage { - command: msg, - session: session.clone(), - }) - .expect("TODO: deal with this"); - trace!(session = session; "Sent"); - } - } - } - FSEvent::Err(err) => { - error!(error = err; "Error in FS event listener") - } - _ => { - debug!(message = as_debug!(res); "Ignoing FS event") - } - } - - LoopControl::Cont(Ok(())) - } - Err(err) => match err { - RecvError::Closed => LoopControl::Break, - RecvError::Lagged(ammount) => { - warn!(messages = ammount; "FSEvents lagged"); - LoopControl::Cont(Ok(())) - } - }, - } - } - .await; - - match res { - LoopControl::Break => break, - LoopControl::Cont(result) => result.expect("TODO: deal with this"), - } - } - }); + // let mut reader = self.watcher.get_event_reader().await; + // let sending_map = self._sending_map.clone(); + // let file_path = self.path.clone(); + // let crc32 = self.crc32.clone(); + // let contents = self.contents.clone(); + // let version = self.version.clone(); + // let history = self.history.clone(); + // let channel_id = info.id.clone(); + // tokio::spawn(async move { + // loop { + // let res = async { + // match reader.recv().await { + // Ok(res) => { + + // LoopControl::Cont(Ok(())) + // } + // Err(err) => match err { + // RecvError::Closed => LoopControl::Break, + // RecvError::Lagged(ammount) => { + // warn!(messages = ammount; "FSEvents lagged"); + // LoopControl::Cont(Ok(())) + // } + // }, + // } + // } + // .await; + + // match res { + // LoopControl::Break => break, + // LoopControl::Cont(result) => result.expect("TODO: deal with this"), + // } + // } + // }); return Ok(Some(link_response)); } else { @@ -282,12 +172,11 @@ impl traits::Service for OT { goval::command::Body::Ot(ot) => { let mut cursor: usize = 0; - let mut contents = self.contents.write().await; for op in ot.op.clone() { match op.op_component.unwrap() { goval::ot_op_component::OpComponent::Skip(_skip) => { let skip: usize = _skip.try_into()?; - if skip + cursor > contents.len_chars() { + if skip + cursor > self.contents.len_chars() { let mut err = goval::Command::default(); err.body = Some(goval::command::Body::Error( "Invalid skip past bounds".to_string(), @@ -299,7 +188,7 @@ impl traits::Service for OT { } goval::ot_op_component::OpComponent::Delete(_delete) => { let delete: usize = _delete.try_into()?; - if delete + cursor > contents.len_chars() { + if delete + cursor > self.contents.len_chars() { let mut err = goval::Command::default(); err.body = Some(goval::command::Body::Error( "Invalid delete past bounds".to_string(), @@ -307,18 +196,16 @@ impl traits::Service for OT { return Ok(Some(err)); } - contents.remove(cursor..(cursor + delete)) + self.contents.remove(cursor..(cursor + delete)) } goval::ot_op_component::OpComponent::Insert(insert) => { - contents.insert(cursor, &insert) + self.contents.insert(cursor, &insert) } } } - let to_write = contents.to_string(); - let mut version = self.version.write().await; - *version += 1; - let saved_version = version.clone(); + let to_write = self.contents.to_string(); + self.version += 1; // drop(version); let user_id; @@ -331,10 +218,9 @@ impl traits::Service for OT { user_id = 23054564 // https://replit.com/@homeval-user } } - + let crc32 = crc32fast::hash(to_write.as_bytes()); - let mut _crc32 = self.crc32.write().await; - *_crc32 = crc32; + self.crc32 = crc32; let committed = Some(prost_types::Timestamp { seconds: SystemTime::now() @@ -345,8 +231,8 @@ impl traits::Service for OT { }); let packet = goval::OtPacket { - spooky_version: saved_version, - version: saved_version, + spooky_version: self.version, + version: self.version, op: ot.op, committed, crc32, @@ -355,9 +241,7 @@ impl traits::Service for OT { author: ot.author, }; - let mut history = self.history.write().await; - history.push(packet.clone()); - // drop(history); + self.history.push(packet.clone()); let mut ot_notif = goval::Command::default(); ot_notif.body = Some(goval::command::Body::Ot(packet)); @@ -400,17 +284,14 @@ impl traits::Service for OT { let mut packets: Vec = vec![]; let from = (request.version_from - 1) as usize; let to = request.version_to as usize; - let history = self.history.read().await; - for (index, item) in history.iter().enumerate() { + for (index, item) in self.history.iter().enumerate() { if index >= from && index <= to { packets.push(item.clone()) } } let mut history_result = goval::Command::default(); - let _inner = goval::OtFetchResponse { - packets - }; + let _inner = goval::OtFetchResponse { packets }; history_result.body = Some(goval::command::Body::OtFetchResponse(_inner)); Ok(Some(history_result)) @@ -427,6 +308,67 @@ impl traits::Service for OT { } } + async fn fsevent(&mut self, info: &super::types::ChannelInfo, event: FSEvent) -> Result<()> { + trace!(event = as_debug!(event), file_path = self.path; "oooh event"); + match event { + FSEvent::Modify(path) => { + trace!(condition = (path == self.path), path = path, file_path = self.path; "Conditional time"); + if path == self.path { + let new_contents = fs::read(&path).await?; + + let new_crc32 = crc32fast::hash(&new_contents); + if new_crc32 == self.crc32 { + return Ok(()); + } + + self.version += 1; + + let new_contents = + String::from_utf8(new_contents).expect("TODO: Deal with this"); + + let ops = diff(self.contents.to_string(), new_contents.clone()); + + self.contents = new_contents.into(); + + let committed = Some(prost_types::Timestamp { + seconds: SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() as i64, + nanos: 0, + }); + + let packet = goval::OtPacket { + spooky_version: self.version, + version: self.version, + op: ops, + committed, + crc32: new_crc32, + nonce: 0, + user_id: 0, + author: goval::ot_packet::Author::User.into(), + }; + + self.history.push(packet.clone()); + + let mut ot_notif = goval::Command::default(); + ot_notif.body = Some(goval::command::Body::Ot(packet)); + + info.send(ot_notif, crate::SendSessions::Everyone).await?; + } + Ok(()) + } + FSEvent::Err(err) => { + error!(error = err; "Error in FS event listener"); + Ok(()) + } + _ => { + debug!(message = as_debug!(event); "Ignoing FS event"); + Ok(()) + } + } + } + async fn attach( &mut self, _info: &super::types::ChannelInfo, @@ -434,10 +376,6 @@ impl traits::Service for OT { session: i32, sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { - let mut sending_map = self._sending_map.write().await; - sending_map.insert(session, sender); - drop(sending_map); - if &self.path == "" { let mut cmd = goval::Command::default(); cmd.body = Some(goval::command::Body::Otstatus(goval::OtStatus::default())); @@ -455,11 +393,12 @@ impl traits::Service for OT { } let _inner = goval::OtStatus { - contents: self.contents.read().await.to_string(), - version: self.version.read().await.clone(), + contents: self.contents.to_string(), + version: self.version, linked_file: Some(file), - cursors: cursors, + cursors, }; + status.body = Some(goval::command::Body::Otstatus(_inner)); Ok(Some(status)) diff --git a/services/src/traits.rs b/services/src/traits.rs index e667050..87bb215 100644 --- a/services/src/traits.rs +++ b/services/src/traits.rs @@ -1,7 +1,7 @@ use anyhow::Result; use async_trait::async_trait; -use crate::{ClientInfo, IPCMessage}; +use crate::{ClientInfo, FSEvent, IPCMessage}; #[async_trait] pub(crate) trait Service { @@ -21,6 +21,10 @@ pub(crate) trait Service { Ok(None) } + async fn fsevent(&mut self, _info: &super::types::ChannelInfo, _event: FSEvent) -> Result<()> { + Ok(()) + } + async fn attach( &mut self, _info: &super::types::ChannelInfo, diff --git a/services/src/types/channel_info.rs b/services/src/types/channel_info.rs index e97a9d3..c87c7ce 100644 --- a/services/src/types/channel_info.rs +++ b/services/src/types/channel_info.rs @@ -19,6 +19,7 @@ pub struct ChannelInfo { pub service: String, pub name: Option, pub sessions: HashMap, + pub sender: tokio::sync::mpsc::UnboundedSender, } impl ChannelInfo { diff --git a/services/src/types/fs_watcher.rs b/services/src/types/fs_watcher.rs index 59e3148..955d450 100644 --- a/services/src/types/fs_watcher.rs +++ b/services/src/types/fs_watcher.rs @@ -11,6 +11,8 @@ use anyhow::Result; use std::{path::Path, time::Duration}; use tokio::sync::broadcast; +use crate::ChannelMessage; + // static FILE_WATCHER_MAP: LazyLock< // RwLock>>>>, // > = LazyLock::new(|| RwLock::new(HashMap::new())); @@ -31,13 +33,14 @@ pub enum FSEvent { pub struct FSWatcher { debouncer: Debouncer, - writer: broadcast::Sender, - reader: broadcast::Receiver, + writer: tokio::sync::mpsc::UnboundedSender, } impl FSWatcher { - pub async fn new() -> Result { - let (writer, reader) = broadcast::channel::(5); + pub async fn new( + writer: tokio::sync::mpsc::UnboundedSender, + ) -> Result { + // let (writer, reader) = broadcast::channel::(5); // FILE_WATCHER_MESSAGES // .write() @@ -54,14 +57,14 @@ impl FSWatcher { Ok(events) => events.iter().for_each(|event| { if let Some(final_event) = notify_event_to_final(event).unwrap() { debounce_writer - .send(final_event) + .send(ChannelMessage::FSEvent(final_event)) .expect("TODO: handle this"); } }), Err(errors) => errors.iter().for_each(|error| { error!(error = as_debug!(error); "Error in debouncer"); debounce_writer - .send(FSEvent::Err(error.to_string())) + .send(ChannelMessage::FSEvent(FSEvent::Err(error.to_string()))) .expect("TODO: handle this"); }), }, @@ -73,11 +76,7 @@ impl FSWatcher { .await??; // }); - Ok(FSWatcher { - debouncer, - reader, - writer, - }) + Ok(FSWatcher { debouncer, writer }) } pub async fn watch(&mut self, files: Vec) -> Result<()> { @@ -98,10 +97,6 @@ impl FSWatcher { self.debouncer.stop_nonblocking(); drop(self.writer) } - - pub async fn get_event_reader(&mut self) -> broadcast::Receiver { - self.reader.resubscribe() - } } fn notify_event_to_final(event: &Event) -> Result> { diff --git a/services/src/types/messaging.rs b/services/src/types/messaging.rs index b0da2c5..37e0178 100644 --- a/services/src/types/messaging.rs +++ b/services/src/types/messaging.rs @@ -28,6 +28,7 @@ pub enum ChannelMessage { Detach(i32), ProcessDead(u32, i32), CmdDead(i32), + FSEvent(super::FSEvent), Replspace(i32, ReplspaceMessage), // session, message Shutdown, // Shutdown the service, value has to be true so that runtime.js can match it in an if check } diff --git a/services/src/types/mod.rs b/services/src/types/mod.rs index b5cce38..1e84859 100644 --- a/services/src/types/mod.rs +++ b/services/src/types/mod.rs @@ -12,3 +12,5 @@ pub use fs_watcher::{FSEvent, FSWatcher}; pub mod service; pub use service::ServiceMetadata; + +// pub mod pty; diff --git a/services/src/types/pty.rs b/services/src/types/pty.rs new file mode 100644 index 0000000..c3899f9 --- /dev/null +++ b/services/src/types/pty.rs @@ -0,0 +1,344 @@ +use futures_util::{future::abortable, stream::AbortHandle}; +use log::{error, warn}; +use portable_pty::PtySize; +use std::{ + collections::{HashMap, VecDeque}, + hash::Hash, + io::{Error, ErrorKind, Write}, + sync::Arc, +}; + +use super::IPCMessage; + +use anyhow::{format_err, Result}; +use tokio::sync::{Mutex, RwLock}; +// use deno_core::{error::AnyError, op, OpDecl}; + +use super::ChannelMessage; + +// static PTY_CANCELLATION_MAP: LazyLock>> = +// LazyLock::new(|| RwLock::new(HashMap::new())); +// static PTY_SESSION_MAP: LazyLock>>> = +// LazyLock::new(|| RwLock::new(HashMap::new())); + +struct PtyWriter { + channel: i32, + sessions: Arc>>>, +} + +impl Write for PtyWriter { + fn write(&mut self, buf: &[u8]) -> std::io::Result { + let mut cmd = goval::Command::default(); + let output: String; + match String::from_utf8(buf.to_vec()) { + Ok(str) => output = str, + Err(err) => { + error!("Invalid utf-8 output in pty handler"); + + return Err(Error::new(ErrorKind::Other, err.utf8_error())); + } + } + + cmd.body = Some(goval::command::Body::Output(output)); + cmd.channel = self.channel; + + let sessions = self.sessions.blocking_read(); + + for (session, sender) in sessions.iter() { + let mut to_send = cmd.clone(); + to_send.session = *session; + + match sender.send(IPCMessage { + command: to_send, + session: *session, + }) { + Ok(_) => {} + Err(err) => { + return Err(Error::new(ErrorKind::Other, err)); + } + } + } + + Ok(buf.len()) + } + + fn flush(&mut self) -> std::io::Result<()> { + Ok(()) + } +} + +struct Pty { + channel: i32, + sessions: Arc>>>, +} + +impl Pty { + pub async fn start( + _args: Vec, + channel: i32, + sessions: Arc>>>, + _env: Option>, + ) -> Result { + let pty = Pty { channel, sessions }; + let env = match _env { + Some(env) => env, + None => HashMap::new(), + }; + + let pty_system = portable_pty::native_pty_system(); + + // Create a new pty + let pair = pty_system.openpty(PtySize { + rows: 24, + cols: 80, + // Not all systems support pixel_width, pixel_height, + // but it is good practice to set it to something + // that matches the size of the selected font. That + // is more complex than can be shown here in this + // brief example though! + pixel_width: 0, + pixel_height: 0, + })?; + + let mut cmd = portable_pty::CommandBuilder::new(_args[0].clone()); + let args = &mut VecDeque::from(_args.to_vec()); + VecDeque::pop_front(args); + for arg in args { + cmd.arg(arg); + } + cmd.cwd(std::env::current_dir()?); + + for (key, val) in env.into_iter() { + cmd.env(key, val) + } + + let child = pair.slave.spawn_command(cmd)?; + + // TODO: recode checkpoint + + let mut reader = pair.master.try_clone_reader()?; + let mut writer = pair.master.take_writer()?; + + let pty_id = child.process_id().expect("Missing process id????"); + + let child_lock = Arc::new(Mutex::new(child)); + + let child_lock_reaper = child_lock.clone(); + tokio::task::spawn(async move { + if let Err(err) = tokio::task::spawn_blocking(move || { + std::io::copy(&mut reader, &mut PtyWriter { channel, sessions }) + }) + .await + { + error!("Error occurred copying from pty to channels: {}", err); + }; + + // let _read = crate::CHANNEL_MESSAGES.read().await; + // if !_read.contains_key(&channel) { + // return Err(format_err!("Owning channel")); + // } + + // let exit_code; + + // if let Some(code) = child_lock_reaper.lock().await.try_wait()? { + // exit_code = code.exit_code() as i32; + // } else {s + // exit_code = 0; + // } + + // let queue = _read.get(&channel).unwrap().clone(); + // drop(_read); + // queue.push(ChannelMessage::ProcessDead(pty_id, exit_code)); + Ok(()) + }); + + tokio::spawn(async move { + match task.await { + Ok(err) => { + error!("Error occurred while passing writes to pty: {}", err) + } + Err(_) => { + let mut child = child_lock.lock().await; + match child.kill() { + Ok(_) => {} + Err(err) => { + warn!("Failed to kill pty child: {}", err) + } + } + drop(child); + } + } + }); + + Ok(pty) + } +} + +async fn op_register_pty( + _args: Vec, + channel: i32, + sessions: Option>, + _env: Option>, +) -> Result { + let mut env = crate::CHILD_PROCS_ENV_BASE.read().await.clone(); + + if let Some(env_vars) = _env { + env.extend(env_vars); + } + + let pty_system = portable_pty::native_pty_system(); + + // Create a new pty + let pair = pty_system.openpty(PtySize { + rows: 24, + cols: 80, + // Not all systems support pixel_width, pixel_height, + // but it is good practice to set it to something + // that matches the size of the selected font. That + // is more complex than can be shown here in this + // brief example though! + pixel_width: 0, + pixel_height: 0, + })?; + + // Spawn a shell into the pty + let mut cmd = portable_pty::CommandBuilder::new(_args[0].clone()); + let args = &mut VecDeque::from(_args.to_vec()); + VecDeque::pop_front(args); + for arg in args { + cmd.arg(arg); + } + cmd.cwd(std::env::current_dir()?); + + for (key, val) in env.into_iter() { + cmd.env(key, val) + } + + let child = pair.slave.spawn_command(cmd)?; + + // Read and parse output from the pty with reader + let mut reader = pair.master.try_clone_reader()?; + let mut writer = pair.master.take_writer()?; + + let pty_id = child.process_id().expect("Missing process id????"); + + let child_lock = Arc::new(Mutex::new(child)); + + let child_lock_reaper = child_lock.clone(); + tokio::task::spawn(async move { + if let Err(err) = tokio::task::spawn_blocking(move || { + std::io::copy(&mut reader, &mut PtyWriter { channel, pty_id }) + }) + .await + { + error!("Error occurred copying from pty to channels: {}", err); + }; + + let _read = crate::CHANNEL_MESSAGES.read().await; + if !_read.contains_key(&channel) { + return Err(AnyError::new(Error::new( + std::io::ErrorKind::NotFound, + "Owning channel", + ))); + } + + let exit_code; + + if let Some(code) = child_lock_reaper.lock().await.try_wait()? { + exit_code = code.exit_code() as i32; + } else { + exit_code = 0; + } + + let queue = _read.get(&channel).unwrap().clone(); + drop(_read); + queue.push(ChannelMessage::ProcessDead(pty_id, exit_code)); + Ok(()) + }); + + let queue = Arc::new(deadqueue::unlimited::Queue::new()); + + if let Some(session_map) = sessions { + PTY_SESSION_MAP.write().await.insert(pty_id, session_map); + } else { + PTY_SESSION_MAP.write().await.insert(pty_id, vec![]); + } + + let mut pty_channel_writer = crate::PROCCESS_CHANNEL_TO_ID.write().await; + if pty_channel_writer.contains_key(&channel) { + drop(pty_channel_writer); + return Err(AnyError::new(Error::new( + ErrorKind::AlreadyExists, + "Channel already has a PTY/CMD", + ))); + } else { + pty_channel_writer.insert(channel, pty_id); + } + + drop(pty_channel_writer); + + crate::PROCCESS_WRITE_MESSAGES + .write() + .await + .insert(pty_id, queue.clone()); + + let (task, handle) = abortable(async move { + loop { + let task = queue.pop().await; + if let Err(err) = writer.write(task.as_bytes()) { + return err; + } + } + }); + + PTY_CANCELLATION_MAP.write().await.insert(pty_id, handle); + + tokio::spawn(async move { + match task.await { + Ok(err) => { + error!("Error occurred while passing writes to pty: {}", err) + } + Err(_) => { + let mut child = child_lock.lock().await; + match child.kill() { + Ok(_) => {} + Err(err) => { + warn!("Failed to kill pty child: {}", err) + } + } + drop(child); + } + } + }); + + Ok(pty_id) +} + +// async fn op_pty_write_msg(id: u32, msg: String) -> Result<()> { +// match crate::PROCCESS_WRITE_MESSAGES.read().await.get(&id) { +// Some(queue) => { +// queue.push(msg); + +// Ok(()) +// } +// None => Err(format_err!("Couldn't find pty {} to write to", id)), +// } +// } + +// async fn op_destroy_pty(id: u32, channel_id: i32) -> Result<()> { +// if let Some(cancel) = PTY_CANCELLATION_MAP.read().await.get(&id) { +// cancel.abort(); +// } else { +// return Err(format_err!("Couldn't find pty {} to write to", id)); +// } + +// PTY_CANCELLATION_MAP.write().await.remove(&id); +// PTY_SESSION_MAP.write().await.remove(&id); +// crate::PROCCESS_WRITE_MESSAGES.write().await.remove(&id); +// crate::PROCCESS_CHANNEL_TO_ID +// .write() +// .await +// .remove(&channel_id); + +// Ok(()) +// } diff --git a/src/goval_server.rs b/src/goval_server.rs index 0569330..cb09031 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -268,7 +268,7 @@ async fn open_channel( CHANNEL_MESSAGES .write() .await - .insert(channel_id_held, writer); + .insert(channel_id_held, writer.clone()); let mut metadata = CHANNEL_METADATA.write().await; metadata.insert(channel_id_held, service_data.clone()); @@ -276,9 +276,10 @@ async fn open_channel( trace!(channel = channel_id_held; "Added channel to queue list"); tokio::spawn(async move { - let channel = homeval_services::Channel::new(channel_id, service, _channel_name) - .await - .expect("TODO: Deal with this"); + let channel = + homeval_services::Channel::new(channel_id, service, _channel_name, writer) + .await + .expect("TODO: Deal with this"); channel.start(reader).await; }); found = true; From 2822856f7a5babded878867685c9da40dece18a8 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sun, 8 Oct 2023 17:50:59 -0700 Subject: [PATCH 016/103] feat(services): implemented output service --- .replit | 2 +- Cargo.lock | 2 +- protobuf/Cargo.toml | 2 +- protobuf/src/goval.proto | 2387 ++++++++++++------------- services/src/lib.rs | 24 +- services/src/ot.rs | 12 +- services/src/output.rs | 188 ++ services/src/toolchain.rs | 55 + services/src/traits.rs | 8 + services/src/types/channel_info.rs | 5 + {src => services/src/types}/config.rs | 0 services/src/types/fs_watcher.rs | 1 - services/src/types/messaging.rs | 2 +- services/src/types/mod.rs | 4 +- services/src/types/pty.rs | 347 ++-- src/goval_server.rs | 13 +- src/main.rs | 28 +- 17 files changed, 1609 insertions(+), 1471 deletions(-) create mode 100644 services/src/output.rs create mode 100644 services/src/toolchain.rs rename {src => services/src/types}/config.rs (100%) diff --git a/.replit b/.replit index 9d68a77..9373978 100644 --- a/.replit +++ b/.replit @@ -1,5 +1,5 @@ # The command that runs the program. If the interpreter field is set, it will have priority and this run command will do nothing -run = { args = ["python3", "main.py"] } +run = { args = ["cat"] } # The primary language of the repl. There can be others, though! language = "python3" diff --git a/Cargo.lock b/Cargo.lock index 213e1f1..021218c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1870,7 +1870,7 @@ dependencies = [ [[package]] name = "protobuf" -version = "0.1.0" +version = "0.2.0" dependencies = [ "prost", "prost-build", diff --git a/protobuf/Cargo.toml b/protobuf/Cargo.toml index d4611c1..bf74814 100644 --- a/protobuf/Cargo.toml +++ b/protobuf/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "protobuf" -version = "0.1.0" +version = "0.2.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/protobuf/src/goval.proto b/protobuf/src/goval.proto index b6f3c73..4bf37ce 100644 --- a/protobuf/src/goval.proto +++ b/protobuf/src/goval.proto @@ -1,4 +1,4 @@ -// @replit/protocol 0.3.12 +// @replit/protocol 0.3.31 syntax = "proto3"; package goval; @@ -6,1743 +6,1660 @@ package goval; import "google/protobuf/timestamp.proto"; import "google/protobuf/struct.proto"; import "google/protobuf/field_mask.proto"; +import "google/protobuf/empty.proto"; message Command { - int32 channel = 1; - int32 session = 2; - string ref = 1000; - map traceInfo = 1001; - oneof body { - OpenChannel openChan = 3; - OpenChannelRes openChanRes = 4; - CloseChannel closeChan = 5; - CloseChannelRes closeChanRes = 6; - ContainerState containerState = 9; - PortOpen portOpen = 10; - PortClose portClose = 48; - Toast toast = 11; - ProtocolError protocolError = 45; - Redirect redirect = 12; - AlwaysOn alwaysOn = 13; - RunMain runMain = 16; - Clear clear = 17; - string eval = 20; - string result = 21; - string input = 22; - string output = 23; - string error = 24; - string stderr = 46; - string log = 47; - string record = 422; - SaneTerm saneTerm = 26; - ResizeTerm resizeTerm = 27; - State state = 28; - OK ok = 30; - File persist = 31; - File persistMirror = 41; - File write = 32; - File remove = 33; - Move move = 34; - File tryRemove = 36; - File mkdir = 39; - File stat = 368; - StatResult statRes = 369; - TransferStart transferStart = 320; - TransferChunk transferChunk = 321; - TransferComplete transferComplete = 322; - Transfer transferCancel = 323; - Transfer transfer = 324; - File read = 35; - File readdir = 37; - Files files = 38; - File file = 40; - CheckChanges checkChanges = 42; - Files changedFiles = 43; - LintResults lintResults = 44; - ContainedTest runContainedTest = 70; - TestResult testResult = 71; - string debuggerStart = 90; - RunMain debuggerStep = 91; - DebugStatus debuggerStatus = 92; - EnsurePackages ensurePackages = 100; - Ping ping = 120; - Pong pong = 121; - Hello hello = 122; - Goodbye goodbye = 123; - ProxyGoingAway proxyGoingAway = 124; - Hint hint = 130; - Connect connect = 150; - Send send = 151; - Recv recv = 152; - Disconnect disconnect = 153; - FileAuthReq fileAuthReq = 200; - FileAuthRes fileAuthRes = 201; - MultiFileAuthRes mutliFileAuthRes = 202; - ListObjects listObjects = 205; - ListObjectsResp listObjectsResp = 206; - OTPacket ot = 220; - OTStatus otstatus = 221; - OTLinkFile otLinkFile = 222; - OTLinkFileResponse otLinkFileResponse = 229; - OTCursor otNewCursor = 223; - OTCursor otDeleteCursor = 224; - OTFetchRequest otFetchRequest = 225; - OTFetchResponse otFetchResponse = 226; - OTTransformSelectionRequest otTransformSelectionRequest = 227; - OTTransformSelectionResponse otTransformSelectionResponse = 228; - Flush flush = 251; - Debug debug = 230; - StartVCR startVCR = 231; - ReadVCR readVCR = 232; - VCRLog VCRLog = 233; - Auth auth = 235; - ExecInfo execInfo = 240; - SubscribeFile subscribeFile = 256; - FileEvent fileEvent = 257; - Roster roster = 260; - User join = 261; - User part = 262; - OpenFile openFile = 263; - FileOpened fileOpened = 264; - FollowUser followUser = 265; - UnfollowUser unfollowUser = 268; - UpdateSessionTimestamp updateSessionTimestamp = 266; - SessionTimestampUpdated sessionTimestampUpdated = 267; - Exec exec = 270; - PackageSearch packageSearch = 280; - PackageSearchResp packageSearchResp = 281; - PackageInfo packageInfo = 282; - PackageInfoResp packageInfoResp = 283; - PackageAdd packageAdd = 284; - PackageRemove packageRemove = 285; - PackageInstall packageInstall = 286; - PackageListSpecfile packageListSpecfile = 287; - PackageListSpecfileResp packageListSpecfileResp = 288; - PackageCacheSave packageCacheSave = 289; - ChatMessage chatMessage = 310; - ChatTyping chatTyping = 311; - ChatScrollback chatScrollback = 312; - FSSnapshot fsSnapshot = 330; - FSSnapshotEvent fsSnapshotEvent = 388; - FSLock fsTakeLock = 331; - FSLock fsReleaseLock = 332; - bool hasCap = 335; - SnapshotEvent snapshotEvent = 389; - bool NoninteractiveFSChangeEvent = 392; - Pid1Config pid1Config = 340; - Metrics metrics = 350; - BootStatus bootStatus = 351; - ReadMetaRequest readMetaRequest = 360; - ReadMetaResponse readMetaResponse = 384; - WriteMetaRequest writeMetaRequest = 361; - WriteMetaResponse writeMetaResponse = 385; - AppendMetaRequest appendMetaRequest = 362; - AppendMetaResponse appendMetaResponse = 386; - Audio audio = 363; - PprofRequest pprofRequest = 364; - PprofResponse pprofResponse = 365; - Audio2 audio2 = 366; - PTYConfig PTYConfig = 367; - DebugMain debugMain = 370; - DebugState debugState = 371; - DebugMainReply debugMainReply = 372; - DebugInput debugInput = 373; - DebugOutput debugOutput = 374; - DebugStop debugStop = 375; - DebugLeave debugLeave = 376; - DebugSessions debugSessions = 377; - DebugAddBreakpointRequest debugAddBreakpointRequest = 380; - DebugUpdateBreakpointRequest debugUpdateBreakpointRequest = 387; - DebugRemoveBreakpointRequest debugRemoveBreakpointRequest = 381; - DebugBreakpointEvent debugBreakpointEvent = 383; - DotReplitGetRequest dotReplitGetRequest = 378; - DotReplitGetResponse dotReplitGetResponse = 379; - RunConfigGetRequest runConfigGetRequest = 390; - RunConfigGetResponse runConfigGetResponse = 391; - DotReplitUpdateRequest dotReplitUpdateRequest = 395; - DotReplitUpdateResponse dotReplitUpdateResponse = 396; - StartLSP startLSP = 345; - FirewallDenied firewallDenied = 393; - NixPackageAddRequest nixPackageAddRequest = 410; - NixPackageAddResponse nixPackageAddResponse = 411; - NixPackageRemoveRequest nixPackageRemoveRequest = 412; - NixPackageRemoveResponse nixPackageRemoveResponse = 413; - NixPackageListRequest nixPackageListRequest = 414; - NixPackageListResponse nixPackageListResponse = 415; - NixChannelsRequest nixChannelsRequest = 416; - NixChannelsResponse nixChannelsResponse = 417; - NixChannelLatestStableRequest nixChannelLatestStableRequest = 418; - NixChannelLatestStableResponse nixChannelLatestStableResponse = 419; - NixPackageSearchRequest nixPackageSearchRequest = 420; - NixPackageSearchResponse nixPackageSearchResponse = 421; - UserEvent userEvent = 423; - ReplspaceApiOpenFile replspaceApiOpenFile = 424; - ReplspaceApiCloseFile replspaceApiCloseFile = 425; - ReplspaceApiGetGitHubToken replspaceApiGetGitHubToken = 426; - ReplspaceApiGitHubToken replspaceApiGitHubToken = 427; - Focused focused = 428; - NixModulesGetRequest nixModulesGetRequest = 429; - NixModulesGetResponse nixModulesGetResponse = 430; - NixModulesChanged nixModulesChanged = 431; - NixModulesBuildRequest nixModulesBuildRequest = 432; - PackageSetPackagerRequest packageSetPackagerRequest = 433; - PackageSetPackagerResponse packageSetPackagerResp = 434; - ToolchainGetRequest toolchainGetRequest = 435; - ToolchainGetResponse toolchainGetResponse = 436; - ToolchainChanged toolchainChanged = 437; - ReplspaceApiOpenMultipleFiles replspaceApiOpenMultipleFiles = 438; - NixModulesGetRegistryRequest nixModulesGetRegistryRequest = 439; - NixModulesGetRegistryResponse nixModulesGetRegistryResponse = 440; - } -} - -message NixPackageAddRequest { - repeated string packages = 1; -} - -message NixPackageAddResponse { -} - -message NixPackageRemoveRequest { - repeated string packages = 1; -} - -message NixPackageRemoveResponse { -} - -message NixPackageListRequest { -} - -message NixPackageListResponse { - repeated NixPackage packages = 1; -} + int32 channel = 1; + int32 session = 2; + string ref = 1000; + map traceInfo = 1001; + oneof body { + OpenChannel openChan = 3; + OpenChannelRes openChanRes = 4; + CloseChannel closeChan = 5; + CloseChannelRes closeChanRes = 6; + ContainerState containerState = 9; + PortOpen portOpen = 10; + PortClose portClose = 48; + Toast toast = 11; + ProtocolError protocolError = 45; + Redirect redirect = 12; + AlwaysOn alwaysOn = 13; + RunMain runMain = 16; + Clear clear = 17; + string eval = 20; + string result = 21; + string input = 22; + string output = 23; + string error = 24; + string stderr = 46; + string log = 47; + google.protobuf.Empty inputClose = 49; + OutputBlockStartEvent outputBlockStartEvent = 443; + OutputBlockEndEvent outputBlockEndEvent = 444; + sint32 exitCodeEvent = 445; + bool splitStderrRequest = 446; + SaneTerm saneTerm = 26; + ResizeTerm resizeTerm = 27; + State state = 28; + OK ok = 30; + File persist = 31; + File persistMirror = 41; + File write = 32; + File remove = 33; + Move move = 34; + File tryRemove = 36; + File mkdir = 39; + File stat = 368; + StatResult statRes = 369; + TransferStart transferStart = 320; + TransferChunk transferChunk = 321; + TransferComplete transferComplete = 322; + Transfer transferCancel = 323; + Transfer transfer = 324; + File read = 35; + File readdir = 37; + Files files = 38; + File file = 40; + CheckChanges checkChanges = 42; + Files changedFiles = 43; + LintResults lintResults = 44; + ContainedTest runContainedTest = 70; + TestResult testResult = 71; + string debuggerStart = 90; + RunMain debuggerStep = 91; + DebugStatus debuggerStatus = 92; + EnsurePackages ensurePackages = 100; + Ping ping = 120; + Pong pong = 121; + Hello hello = 122; + Goodbye goodbye = 123; + ProxyGoingAway proxyGoingAway = 124; + Hint hint = 130; + Connect connect = 150; + Send send = 151; + Recv recv = 152; + Disconnect disconnect = 153; + FileAuthReq fileAuthReq = 200; + FileAuthRes fileAuthRes = 201; + MultiFileAuthRes mutliFileAuthRes = 202; + ListObjects listObjects = 205; + ListObjectsResp listObjectsResp = 206; + OTPacket ot = 220; + OTStatus otstatus = 221; + OTLinkFile otLinkFile = 222; + OTLinkFileResponse otLinkFileResponse = 229; + OTCursor otNewCursor = 223; + OTCursor otDeleteCursor = 224; + OTFetchRequest otFetchRequest = 225; + OTFetchResponse otFetchResponse = 226; + OTTransformSelectionRequest otTransformSelectionRequest = 227; + OTTransformSelectionResponse otTransformSelectionResponse = 228; + Flush flush = 251; + Debug debug = 230; + StartVCR startVCR = 231; + ReadVCR readVCR = 232; + VCRLog VCRLog = 233; + Auth auth = 235; + ExecInfo execInfo = 240; + SubscribeFile subscribeFile = 256; + FileEvent fileEvent = 257; + Roster roster = 260; + User join = 261; + User part = 262; + OpenFile openFile = 263; + FileOpened fileOpened = 264; + FollowUser followUser = 265; + UnfollowUser unfollowUser = 268; + UpdateSessionTimestamp updateSessionTimestamp = 266; + SessionTimestampUpdated sessionTimestampUpdated = 267; + Exec exec = 270; + PackageSearch packageSearch = 280; + PackageSearchResp packageSearchResp = 281; + PackageInfo packageInfo = 282; + PackageInfoResp packageInfoResp = 283; + PackageAdd packageAdd = 284; + PackageRemove packageRemove = 285; + PackageInstall packageInstall = 286; + PackageInstallResponse packageInstallResponse = 290; + PackageListSpecfile packageListSpecfile = 287; + PackageListSpecfileResp packageListSpecfileResp = 288; + PackageCacheSave packageCacheSave = 289; + ChatMessage chatMessage = 310; + ChatTyping chatTyping = 311; + ChatScrollback chatScrollback = 312; + FSSnapshot fsSnapshot = 330; + FSSnapshotEvent fsSnapshotEvent = 388; + FSLock fsTakeLock = 331; + FSLock fsReleaseLock = 332; + bool hasCap = 335; + SnapshotEvent snapshotEvent = 389; + bool NoninteractiveFSChangeEvent = 392; + Pid1Config pid1Config = 340; + Metrics metrics = 350; + BootStatus bootStatus = 351; + ReadMetaRequest readMetaRequest = 360; + ReadMetaResponse readMetaResponse = 384; + WriteMetaRequest writeMetaRequest = 361; + WriteMetaResponse writeMetaResponse = 385; + AppendMetaRequest appendMetaRequest = 362; + AppendMetaResponse appendMetaResponse = 386; + Audio audio = 363; + PprofRequest pprofRequest = 364; + PprofResponse pprofResponse = 365; + Audio2 audio2 = 366; + PTYConfig PTYConfig = 367; + DebugMain debugMain = 370; + DebugState debugState = 371; + DebugMainReply debugMainReply = 372; + DebugInput debugInput = 373; + DebugOutput debugOutput = 374; + DebugStop debugStop = 375; + DebugLeave debugLeave = 376; + DebugSessions debugSessions = 377; + DebugAddBreakpointRequest debugAddBreakpointRequest = 380; + DebugUpdateBreakpointRequest debugUpdateBreakpointRequest = 387; + DebugRemoveBreakpointRequest debugRemoveBreakpointRequest = 381; + DebugBreakpointEvent debugBreakpointEvent = 383; + DotReplitGetRequest dotReplitGetRequest = 378; + DotReplitGetResponse dotReplitGetResponse = 379; + RunConfigGetRequest runConfigGetRequest = 390; + RunConfigGetResponse runConfigGetResponse = 391; + DotReplitUpdateRequest dotReplitUpdateRequest = 395; + DotReplitUpdateResponse dotReplitUpdateResponse = 396; + StartLSP startLSP = 345; + FirewallDenied firewallDenied = 393; + NixPackageAddRequest nixPackageAddRequest = 410; + NixPackageAddResponse nixPackageAddResponse = 411; + NixPackageRemoveRequest nixPackageRemoveRequest = 412; + NixPackageRemoveResponse nixPackageRemoveResponse = 413; + NixPackageListRequest nixPackageListRequest = 414; + NixPackageListResponse nixPackageListResponse = 415; + NixChannelsRequest nixChannelsRequest = 416; + NixChannelsResponse nixChannelsResponse = 417; + NixChannelLatestStableRequest nixChannelLatestStableRequest = 418; + NixChannelLatestStableResponse nixChannelLatestStableResponse = 419; + NixPackageSearchRequest nixPackageSearchRequest = 420; + NixPackageSearchResponse nixPackageSearchResponse = 421; + UserEvent userEvent = 423; + ReplspaceApiOpenFile replspaceApiOpenFile = 424; + ReplspaceApiCloseFile replspaceApiCloseFile = 425; + ReplspaceApiGetGitHubToken replspaceApiGetGitHubToken = 426; + ReplspaceApiGitHubToken replspaceApiGitHubToken = 427; + Focused focused = 428; + NixModulesGetRequest nixModulesGetRequest = 429; + NixModulesGetResponse nixModulesGetResponse = 430; + NixModulesChanged nixModulesChanged = 431; + NixModulesBuildRequest nixModulesBuildRequest = 432; + PackageSetPackagerRequest packageSetPackagerRequest = 433; + PackageSetPackagerResponse packageSetPackagerResp = 434; + ToolchainGetRequest toolchainGetRequest = 435; + ToolchainGetResponse toolchainGetResponse = 436; + ToolchainChanged toolchainChanged = 437; + ReplspaceApiOpenMultipleFiles replspaceApiOpenMultipleFiles = 438; + NixModulesGetRegistryRequest nixModulesGetRegistryRequest = 439; + NixModulesGetRegistryResponse nixModulesGetRegistryResponse = 440; + } +} + +message NixPackageAddRequest { repeated string packages = 1; } + +message NixPackageAddResponse {} + +message NixPackageRemoveRequest { repeated string packages = 1; } + +message NixPackageRemoveResponse {} + +message NixPackageListRequest {} + +message NixPackageListResponse { repeated NixPackage packages = 1; } message NixPackage { - string name = 1; - string description = 2; - string version = 3; - repeated string homepageURL = 4; - repeated string maintainers = 5; - repeated string licenses = 6; + string name = 1; + string description = 2; + string version = 3; + repeated string homepageURL = 4; + repeated string maintainers = 5; + repeated string licenses = 6; } -message NixChannelsRequest { -} +message NixChannelsRequest {} -message NixChannelsResponse { - repeated string channels = 1; -} +message NixChannelsResponse { repeated string channels = 1; } -message NixChannelLatestStableRequest { -} +message NixChannelLatestStableRequest {} -message NixChannelLatestStableResponse { - string channel = 1; -} +message NixChannelLatestStableResponse { string channel = 1; } -message NixPackageSearchRequest { - string query = 1; -} +message NixPackageSearchRequest { string query = 1; } -message NixPackageSearchResponse { - repeated NixPackage packages = 1; -} +message NixPackageSearchResponse { repeated NixPackage packages = 1; } message StartLSP { - string language = 1; - string languageServerId = 2; + string language = 1; + string languageServerId = 2; } -message Audio { - repeated int32 data = 1; -} +message Audio { repeated int32 data = 1; } message Audio2 { - repeated sint32 data = 1; - int64 samples = 2; + repeated sint32 data = 1; + int64 samples = 2; } message Preconditions { - int64 generation = 1; - int64 metageneration = 2; - bool doesNotExist = 3; + int64 generation = 1; + int64 metageneration = 2; + bool doesNotExist = 3; } message ReadMetaRequest { - string key = 1; - bool exists = 2; - bytes data = 3; + string key = 1; + bool exists = 2; + bytes data = 3; } message ReadMetaResponse { - string key = 1; - bool exists = 2; - bytes data = 3; - int64 generation = 4; - int64 metageneration = 5; + string key = 1; + bool exists = 2; + bytes data = 3; + int64 generation = 4; + int64 metageneration = 5; } message WriteMetaRequest { - string key = 1; - bytes data = 2; - Preconditions preconditions = 5; + string key = 1; + bytes data = 2; + Preconditions preconditions = 5; } message WriteMetaResponse { - int64 generation = 1; - int64 metageneration = 2; + int64 generation = 1; + int64 metageneration = 2; } message AppendMetaRequest { - string key = 1; - bytes data = 2; - Preconditions preconditions = 5; + string key = 1; + bytes data = 2; + Preconditions preconditions = 5; } message AppendMetaResponse { - int64 generation = 1; - int64 metageneration = 2; + int64 generation = 1; + int64 metageneration = 2; } message BootStatus { - enum Stage { - HANDSHAKE = 0; - ACQUIRING = 3; - COMPLETE = 4; - PROXY = 5; - PULL_FILES = 6; - LOAD_BLOCK = 7; - BLOCK_MIGRATION = 9; - RETRY = 8; - } - - BootStatus.Stage stage = 1; - uint32 progress = 2; - uint32 total = 3; + enum Stage { + HANDSHAKE = 0; + ACQUIRING = 3; + COMPLETE = 4; + PROXY = 5; + PULL_FILES = 6; + LOAD_BLOCK = 7; + BLOCK_MIGRATION = 9; + RETRY = 8; + } + + BootStatus.Stage stage = 1; + uint32 progress = 2; + uint32 total = 3; } message Pid1Config { - string cwd = 1; - string language = 2; - map env = 3; - bool noStore = 4; - bool noninteractiveFSChange = 5; + string cwd = 1; + string language = 2; + map env = 3; + bool noStore = 4; + bool noninteractiveFSChange = 5; } -message FSLock { - string name = 1; -} +message FSLock { string name = 1; } -message FSSnapshot { -} +message FSSnapshot {} -message FSSnapshotEvent { - repeated string sources = 1; -} +message FSSnapshotEvent { repeated string sources = 1; } -message SnapshotEvent { - repeated string sources = 1; -} +message SnapshotEvent { repeated string sources = 1; } -message SubscribeFile { - repeated File files = 1; -} +message SubscribeFile { repeated File files = 1; } message FileEvent { - enum Op { - Create = 0; - Move = 1; - Remove = 2; - Modify = 3; - } + enum Op { + Create = 0; + Move = 1; + Remove = 2; + Modify = 3; + } - File file = 1; - File dest = 3; - FileEvent.Op op = 2; + File file = 1; + File dest = 3; + FileEvent.Op op = 2; } message Flush { - enum Consistency { - PermanentStorage = 0; - Disk = 1; - } + enum Consistency { + PermanentStorage = 0; + Disk = 1; + } - Flush.Consistency consistency = 1; + Flush.Consistency consistency = 1; } message OTLinkFile { - File file = 1; - bool highConsistency = 2; - bool OBSOLETEUseModTime = 3; + File file = 1; + bool highConsistency = 2; + bool OBSOLETEUseModTime = 3; } message OTLinkFileResponse { - uint32 version = 1; - File linkedFile = 2; + uint32 version = 1; + File linkedFile = 2; } message Auth { - string token = 1; - string containerID = 2; + string token = 1; + string containerID = 2; } message VCREntry { - enum Direction { - IN = 0; - OUT = 1; - } + enum Direction { + IN = 0; + OUT = 1; + } - uint64 timestamp = 1; - VCREntry.Direction direction = 2; - Command command = 3; - string uid = 4; - string replid = 5; + uint64 timestamp = 1; + VCREntry.Direction direction = 2; + Command command = 3; + string uid = 4; + string replid = 5; } -message StartVCR { -} +message StartVCR {} -message ReadVCR { -} +message ReadVCR {} message VCRLog { - repeated VCREntry log = 1; - File logfile = 2; + repeated VCREntry log = 1; + File logfile = 2; } message ExecInfo { - repeated string command = 1; - string reason = 2; + repeated string command = 1; + string reason = 2; } -message Debug { - string text = 1; -} +message Debug { string text = 1; } enum FileAuthMethod { - GET = 0; - HEAD = 1; - PUT = 2; - DELETE = 3; + GET = 0; + HEAD = 1; + PUT = 2; + DELETE = 3; } message FileAuthReq { - File file = 1; - FileAuthMethod method = 2; + File file = 1; + FileAuthMethod method = 2; } message MultiFileAuthRes { - FileAuthRes put = 1; - FileAuthRes del = 2; - FileAuthRes get = 3; + FileAuthRes put = 1; + FileAuthRes del = 2; + FileAuthRes get = 3; } message FileAuthRes { - File file = 1; - string url = 2; - FileAuthMethod method = 3; - int64 expire = 4; - string error = 5; - bool replError = 7; + File file = 1; + string url = 2; + FileAuthMethod method = 3; + int64 expire = 4; + string error = 5; + bool replError = 7; } -message ListObjects { - string prefix = 1; -} +message ListObjects { string prefix = 1; } -message ListObjectsResp { - repeated string objects = 1; -} +message ListObjectsResp { repeated string objects = 1; } -message Disconnect { - string error = 1; -} +message Disconnect { string error = 1; } -message Send { - bytes buff = 1; -} +message Send { bytes buff = 1; } -message Recv { - bytes buff = 1; -} +message Recv { bytes buff = 1; } message Connect { - string proto = 1; - string addr = 2; + string proto = 1; + string addr = 2; } -message Hint { - string text = 1; -} +message Hint { string text = 1; } -message Ping { -} +message Ping {} -message Pong { -} +message Pong {} message Hello { - uint32 userid = 1; - string username = 2; - string token = 3; + uint32 userid = 1; + string username = 2; + string token = 3; } -message Goodbye { -} +message Goodbye {} enum State { - Stopped = 0; - Running = 1; + Stopped = 0; + Running = 1; } -message CheckChanges { -} +message CheckChanges {} message EnsurePackages { - bool install = 1; - File file = 2; + bool install = 1; + File file = 2; } -message Start { -} +message Start {} message DebugStatus { - bool done = 1; - repeated StackFrame stack = 2; + bool done = 1; + repeated StackFrame stack = 2; } message StackFrame { - string function = 1; - uint32 line = 2; + string function = 1; + uint32 line = 2; } message ContainedTest { - File suite = 1; - repeated File project = 2; + File suite = 1; + repeated File project = 2; } message TestResult { - bool passed = 1; - string stderr = 2; - repeated TestFailure fails = 3; + bool passed = 1; + string stderr = 2; + repeated TestFailure fails = 3; } message TestFailure { - string name = 1; - string trace = 2; + string name = 1; + string trace = 2; } message ResizeTerm { - uint32 rows = 1; - uint32 cols = 2; + uint32 rows = 1; + uint32 cols = 2; } -message SaneTerm { -} +message SaneTerm {} -message LintResults { - repeated LintResult results = 1; -} +message LintResults { repeated LintResult results = 1; } message LintResult { - string text = 1; - int32 row = 2; - int32 column = 3; - string type = 4; + string text = 1; + int32 row = 2; + int32 column = 3; + string type = 4; } -message OK { -} +message OK {} message Move { - string oldPath = 1; - string newPath = 2; + string oldPath = 1; + string newPath = 2; } -message Files { - repeated File files = 1; -} +message Files { repeated File files = 1; } message StatResult { - bool exists = 1; - File.Type type = 2; - int64 size = 3; - string fileMode = 4; - int64 modTime = 5; + bool exists = 1; + File.Type type = 2; + int64 size = 3; + string fileMode = 4; + int64 modTime = 5; } message File { - enum Type { - REGULAR = 0; - DIRECTORY = 1; - } + enum Type { + REGULAR = 0; + DIRECTORY = 1; + } - string path = 1; - File.Type type = 2; - bytes content = 3; + string path = 1; + File.Type type = 2; + bytes content = 3; } -message Transfer { - string id = 1; -} +message Transfer { string id = 1; } message TransferStart { - string path = 1; - int64 size = 2; + string path = 1; + int64 size = 2; } message TransferChunk { - string id = 1; - bytes content = 2; + string id = 1; + bytes content = 2; } message TransferComplete { - string id = 1; - uint32 crc32 = 2; + string id = 1; + uint32 crc32 = 2; } -message Clear { -} +message Clear {} -message Toast { - string text = 1; -} +message Toast { string text = 1; } -message ProtocolError { - string text = 1; -} +message ProtocolError { string text = 1; } -message Redirect { - string url = 1; -} +message Redirect { string url = 1; } -message AlwaysOn { - bool enable = 1; -} +message AlwaysOn { bool enable = 1; } message RunMain { - enum RunMode { - RUN = 0; - RECORD = 1; - } + enum RunMode { + RUN = 0; + RECORD = 1; + } - RunMain.RunMode runMode = 1; - bool idempotent = 2; - string filePath = 3; - string runnerId = 4; + RunMain.RunMode runMode = 1; + bool idempotent = 2; + string filePath = 3; + string runnerId = 4; + bool fromHosting = 5; } message OpenChannel { - enum Action { - CREATE = 0; - ATTACH = 1; - ATTACH_OR_CREATE = 2; - } + enum Action { + CREATE = 0; + ATTACH = 1; + ATTACH_OR_CREATE = 2; + } - string service = 1; - string name = 2; - OpenChannel.Action action = 3; - int32 id = 4; + string service = 1; + string name = 2; + OpenChannel.Action action = 3; + int32 id = 4; } message OpenChannelRes { - enum State { - CREATED = 0; - ATTACHED = 1; - ERROR = 2; - } + enum State { + CREATED = 0; + ATTACHED = 1; + ERROR = 2; + } - int32 id = 1; - OpenChannelRes.State state = 2; - string error = 3; + int32 id = 1; + OpenChannelRes.State state = 2; + string error = 3; } message CloseChannel { - enum Action { - DISCONNECT = 0; - TRY_CLOSE = 1; - CLOSE = 2; - } + enum Action { + DISCONNECT = 0; + TRY_CLOSE = 1; + CLOSE = 2; + } - int32 id = 1; - CloseChannel.Action action = 2; + int32 id = 1; + CloseChannel.Action action = 2; } message CloseChannelRes { - enum Status { - DISCONNECT = 0; - CLOSE = 1; - NOTHING = 2; - } + enum Status { + DISCONNECT = 0; + CLOSE = 1; + NOTHING = 2; + } - int32 id = 1; - CloseChannelRes.Status status = 2; + int32 id = 1; + CloseChannelRes.Status status = 2; } message ContainerState { - enum State { - SLEEP = 0; - READY = 1; - } + enum State { + SLEEP = 0; + READY = 1; + } - ContainerState.State state = 1; + ContainerState.State state = 1; } message PortOpen { - bool forwarded = 1; - uint32 port = 2; - string address = 3; - uint32 externalPort = 4; + bool forwarded = 1; + uint32 port = 2; + string address = 3; + uint32 externalPort = 4; + string comm = 5; + repeated string cmdline = 6; + uint32 pid = 7; } message PortClose { - uint32 port = 2; - string address = 3; - uint32 externalPort = 4; + uint32 port = 2; + string address = 3; + uint32 externalPort = 4; } message OTFetchRequest { - uint32 versionFrom = 1; - uint32 versionTo = 2; + uint32 versionFrom = 1; + uint32 versionTo = 2; } -message OTFetchResponse { - repeated OTPacket packets = 1; -} +message OTFetchResponse { repeated OTPacket packets = 1; } message OTTransformSelectionRequest { - uint32 indexStart = 1; - uint32 indexEnd = 2; - uint32 versionFrom = 3; - uint32 versionTo = 4; + uint32 indexStart = 1; + uint32 indexEnd = 2; + uint32 versionFrom = 3; + uint32 versionTo = 4; } message OTTransformSelectionResponse { - uint32 indexStart = 1; - uint32 indexEnd = 2; - uint32 version = 3; + uint32 indexStart = 1; + uint32 indexEnd = 2; + uint32 version = 3; } message OTPacket { - enum Author { - USER = 0; - GHOSTWRITER = 1; - } + enum Author { + USER = 0; + GHOSTWRITER = 1; + } - uint32 spookyVersion = 1; - uint32 version = 5; - repeated OTOpComponent op = 2; - uint32 crc32 = 3; - google.protobuf.Timestamp committed = 4; - uint32 nonce = 6; - uint32 userId = 7; - OTPacket.Author author = 8; + uint32 spookyVersion = 1; + uint32 version = 5; + repeated OTOpComponent op = 2; + uint32 crc32 = 3; + google.protobuf.Timestamp committed = 4; + uint32 nonce = 6; + uint32 userId = 7; + OTPacket.Author author = 8; } message OTOpComponent { - oneof opComponent { - uint32 skip = 1; - uint32 delete = 2; - string insert = 3; - } + oneof opComponent { + uint32 skip = 1; + uint32 delete = 2; + string insert = 3; + } } message OTStatus { - string contents = 1; - uint32 version = 2; - File linkedFile = 3; - repeated OTCursor cursors = 4; + string contents = 1; + uint32 version = 2; + File linkedFile = 3; + repeated OTCursor cursors = 4; } message OTCursor { - uint32 position = 1; - uint32 selectionStart = 2; - uint32 selectionEnd = 3; - User user = 4; - string id = 5; + uint32 position = 1; + uint32 selectionStart = 2; + uint32 selectionEnd = 3; + User user = 4; + string id = 5; } message ChatMessage { - string username = 1; - string text = 2; + string username = 1; + string text = 2; } message ChatTyping { - string username = 1; - bool typing = 2; + string username = 1; + bool typing = 2; } message User { - uint32 id = 1; - string name = 2; - repeated string roles = 3; - int32 session = 4; - repeated string teams = 5; - string bio = 6; - string url = 7; - string profileImage = 8; + uint32 id = 1; + string name = 2; + repeated string roles = 3; + int32 session = 4; + repeated string teams = 5; + string bio = 6; + string url = 7; + string profileImage = 8; } message Roster { - repeated User user = 1; - repeated FileOpened files = 2; + repeated User user = 1; + repeated FileOpened files = 2; } -message OpenFile { - string file = 1; -} +message OpenFile { string file = 1; } message FileOpened { - uint32 userId = 1; - string file = 2; - int32 session = 3; - google.protobuf.Timestamp timestamp = 4; + uint32 userId = 1; + string file = 2; + int32 session = 3; + google.protobuf.Timestamp timestamp = 4; } message ReplspaceApiOpenFile { - string file = 1; - bool waitForClose = 2; - string nonce = 3; + string file = 1; + bool waitForClose = 2; + string nonce = 3; } message ReplspaceApiCloseFile { - string file = 1; - string nonce = 2; + string file = 1; + string nonce = 2; } -message ReplspaceApiGetGitHubToken { - string nonce = 1; -} +message ReplspaceApiGetGitHubToken { string nonce = 1; } message ReplspaceApiGitHubToken { - string nonce = 1; - string token = 2; + string nonce = 1; + string token = 2; } -message ReplspaceApiOpenMultipleFiles { - repeated string files = 1; -} +message ReplspaceApiOpenMultipleFiles { repeated string files = 1; } -message Focused { -} +message Focused {} -message UpdateSessionTimestamp { -} +message UpdateSessionTimestamp {} message SessionTimestampUpdated { - int32 session = 1; - google.protobuf.Timestamp timestamp = 2; + int32 session = 1; + google.protobuf.Timestamp timestamp = 2; } -message FollowUser { - int32 session = 1; -} +message FollowUser { int32 session = 1; } -message UnfollowUser { - int32 session = 1; -} +message UnfollowUser { int32 session = 1; } message Exec { - enum Lifecycle { - NON_BLOCKING = 0; - BLOCKING = 1; - STDIN = 2; - } + enum Lifecycle { + NON_BLOCKING = 0; + BLOCKING = 1; + STDIN = 2; + } - repeated string args = 1; - map env = 2; - bool blocking = 3; - Exec.Lifecycle lifecycle = 6; - bool splitStderr = 4; - bool splitLogs = 5; + repeated string args = 1; + map env = 2; + bool blocking = 3; + Exec.Lifecycle lifecycle = 6; + bool splitStderr = 4; + bool splitLogs = 5; } message Package { - string name = 1; - string spec = 2; - string description = 10; - string version = 11; - string homepageURL = 12; - string documentationURL = 13; - string sourceCodeURL = 14; - string bugTrackerURL = 15; - string author = 16; - string license = 17; - repeated Package dependencies = 18; + string name = 1; + string spec = 2; + string description = 10; + string version = 11; + string homepageURL = 12; + string documentationURL = 13; + string sourceCodeURL = 14; + string bugTrackerURL = 15; + string author = 16; + string license = 17; + repeated Package dependencies = 18; } -message PackageSetPackagerRequest { - string packagerId = 1; -} +message PackageSetPackagerRequest { string packagerId = 1; } -message PackageSetPackagerResponse { - string packagerId = 1; -} +message PackageSetPackagerResponse { string packagerId = 1; } -message PackageSearch { - string query = 1; -} +message PackageSearch { string query = 1; } -message PackageSearchResp { - repeated Package results = 1; -} +message PackageSearchResp { repeated Package results = 1; } -message PackageInfo { - Package pkg = 1; -} +message PackageInfo { Package pkg = 1; } -message PackageInfoResp { - Package pkg = 1; -} +message PackageInfoResp { Package pkg = 1; } -message PackageAdd { - repeated Package pkgs = 1; -} +message PackageAdd { repeated Package pkgs = 1; } -message PackageRemove { - repeated Package pkgs = 1; -} +message PackageRemove { repeated Package pkgs = 1; } message PackageInstall { - bool fromHosting = 1; + bool fromHosting = 1; + bool disableGuess = 2; + bool useNewResponse = 99; } -message PackageListSpecfile { +message PackageInstallResponse { + repeated string guessedPkgs = 1; + int64 upmGuessDurationMs = 2; + int64 upmAddDurationMs = 3; + int64 upmLockDurationMs = 4; + int64 totalDurationMs = 5; } -message PackageListSpecfileResp { - repeated Package pkgs = 1; -} +message PackageListSpecfile {} -message PackageCacheSave { -} +message PackageListSpecfileResp { repeated Package pkgs = 1; } -message ChatScrollback { - repeated ChatMessage scrollback = 1; -} +message PackageCacheSave {} -message Metrics { - repeated bytes prometheusMetricFamilies = 1; -} +message ChatScrollback { repeated ChatMessage scrollback = 1; } + +message Metrics { repeated bytes prometheusMetricFamilies = 1; } message PprofRequest { - string id = 1; - oneof body { - PprofCpuProfileRequest pprofCpuProfileRequest = 2; - PprofHeapProfileRequest pprofHeapProfileRequest = 3; - PprofAllocsProfileRequest pprofAllocsProfileRequest = 4; - PprofBlockProfileRequest pprofBlockProfileRequest = 5; - PprofMutexProfileRequest pprofMutexProfileRequest = 6; - } + string id = 1; + oneof body { + PprofCpuProfileRequest pprofCpuProfileRequest = 2; + PprofHeapProfileRequest pprofHeapProfileRequest = 3; + PprofAllocsProfileRequest pprofAllocsProfileRequest = 4; + PprofBlockProfileRequest pprofBlockProfileRequest = 5; + PprofMutexProfileRequest pprofMutexProfileRequest = 6; + } } -message PprofAllocsProfileRequest { - bool debug = 1; -} +message PprofAllocsProfileRequest { bool debug = 1; } -message PprofBlockProfileRequest { - bool debug = 1; -} +message PprofBlockProfileRequest { bool debug = 1; } -message PprofCpuProfileRequest { - int64 seconds = 1; -} +message PprofCpuProfileRequest { int64 seconds = 1; } message PprofHeapProfileRequest { - bool gc = 1; - bool debug = 2; + bool gc = 1; + bool debug = 2; } -message PprofMutexProfileRequest { - bool debug = 1; -} +message PprofMutexProfileRequest { bool debug = 1; } message PprofResponse { - string id = 1; - bytes profile = 2; + string id = 1; + bytes profile = 2; } -message PTYConfig { - bool pipeMode = 1; -} +message PTYConfig { bool pipeMode = 1; } message DebugMain { - string session = 1; - bool readOnly = 2; - string filePath = 3; - string debuggerId = 4; + string session = 1; + bool readOnly = 2; + string filePath = 3; + string debuggerId = 4; } message DebugMainReply { - enum Protocol { - DAP = 0; - } + enum Protocol { + DAP = 0; + } - bool joined = 1; - DebugMainReply.Protocol protocol = 2; + bool joined = 1; + DebugMainReply.Protocol protocol = 2; } message DebugState { - string session = 1; - State state = 2; + string session = 1; + State state = 2; } message DebugInput { - string session = 1; - oneof stream { - string input = 2; - string adapterInput = 3; - } + string session = 1; + oneof stream { + string input = 2; + string adapterInput = 3; + } } message DebugOutput { - string session = 1; - oneof stream { - string output = 2; - string adapterOutput = 3; - } + string session = 1; + oneof stream { + string output = 2; + string adapterOutput = 3; + } } -message DebugStop { - string session = 1; -} +message DebugStop { string session = 1; } -message DebugLeave { - string session = 1; -} +message DebugLeave { string session = 1; } -message DebugSessions { - map sessions = 1; -} +message DebugSessions { map sessions = 1; } -message DotReplitGetRequest { -} +message DotReplitGetRequest {} -message DotReplitGetResponse { - DotReplit dotReplit = 1; -} +message DotReplitGetResponse { DotReplit dotReplit = 1; } -message RunConfigGetRequest { -} +message RunConfigGetRequest {} message RunConfigGetResponse { - message Run { - Exec compile = 1; - Exec run = 2; - } + message Run { + Exec compile = 1; + Exec run = 2; + } - oneof config { - DotReplitInterp interp = 1; - RunConfigGetResponse.Run run = 2; - } + oneof config { + DotReplitInterp interp = 1; + RunConfigGetResponse.Run run = 2; + } } message DotReplitUpdateOp { - string op = 1; - string path = 2; - string value = 3; + string op = 1; + string path = 2; + string value = 3; } -message DotReplitUpdateRequest { - repeated DotReplitUpdateOp ops = 1; -} +message DotReplitUpdateRequest { repeated DotReplitUpdateOp ops = 1; } -message DotReplitUpdateResponse { -} +message DotReplitUpdateResponse {} message DebugAddBreakpointRequest { - string path = 1; - uint32 otVersion = 2; - uint32 otIndex = 3; - bool sessionLocal = 6; - int32 line = 4; - string logMessage = 5; + string path = 1; + uint32 otVersion = 2; + uint32 otIndex = 3; + bool sessionLocal = 6; + int32 line = 4; + string logMessage = 5; } message DebugUpdateBreakpointRequest { - string breakpointId = 1; - string logMessage = 2; + string breakpointId = 1; + string logMessage = 2; } -message DebugRemoveBreakpointRequest { - string breakpointId = 2; -} +message DebugRemoveBreakpointRequest { string breakpointId = 2; } message DebugBreakpointEvent { - string path = 1; - string absolutePath = 3; - repeated DebugBreakpoint breakpoints = 2; + string path = 1; + string absolutePath = 3; + repeated DebugBreakpoint breakpoints = 2; } message DebugBreakpoint { - string breakpointId = 1; - int32 line = 2; - uint32 otVersion = 3; - uint32 otIndex = 4; - bool sessionLocal = 6; - string logMessage = 5; + string breakpointId = 1; + int32 line = 2; + uint32 otVersion = 3; + uint32 otIndex = 4; + bool sessionLocal = 6; + string logMessage = 5; } message DotReplit { - Exec run = 1; - Exec compile = 2; - DebuggerConfig debugger = 3; - string language = 4; - Exec onBoot = 5; - DotReplitPackager packager = 6; - DotReplitInterp interpreter = 7; - string entrypoint = 8; - map languages = 9; - DotReplitUnitTest unitTest = 10; - repeated string hidden = 11; - NixConfig nix = 12; - bool audio = 13; - HostingConfig hosting = 14; - map env = 15; - GitHubImportConfig gitHubImport = 16; - AuthConfig auth = 17; - repeated DotReplitHint hintsList = 18; - repeated DotReplitPort ports = 19; - repeated DotReplitEnvVar orderedEnv = 20; - repeated string refreshWebViewOnFileChange = 21; - DeploymentConfig deployment = 22; - repeated string modules = 23; - ExtensionConfig extension = 24; + Exec run = 1; + Exec compile = 2; + DebuggerConfig debugger = 3; + string language = 4; + Exec onBoot = 5; + DotReplitPackager packager = 6; + DotReplitInterp interpreter = 7; + string entrypoint = 8; + map languages = 9; + DotReplitUnitTest unitTest = 10; + repeated string hidden = 11; + NixConfig nix = 12; + bool audio = 13; + HostingConfig hosting = 14; + map env = 15; + GitHubImportConfig gitHubImport = 16; + AuthConfig auth = 17; + repeated DotReplitHint hintsList = 18; + repeated DotReplitPort ports = 19; + repeated DotReplitEnvVar orderedEnv = 20; + repeated string refreshWebViewOnFileChange = 21; + DeploymentConfig deployment = 22; + repeated string modules = 23; + ExtensionConfig extension = 24; + RulesConfig rules = 25; } message DotReplitEnvVar { - string key = 1; - string value = 2; + string key = 1; + string value = 2; } message DotReplitPort { - uint32 localPort = 1; - uint32 externalPort = 2; + uint32 localPort = 1; + uint32 externalPort = 2; } message DotReplitHint { - string regex = 1; - string message = 2; + string regex = 1; + string message = 2; } -message GitHubImportConfig { - repeated string requiredFiles = 1; -} +message GitHubImportConfig { repeated string requiredFiles = 1; } message DeploymentConfig { - enum Target { - GCE = 0; - CLOUDRUN = 1; - STATIC = 2; - } + enum Target { + GCE = 0; + CLOUDRUN = 1; + STATIC = 2; + } - Exec run = 1; - Exec build = 2; - bool ignorePorts = 3; - DeploymentConfig.Target target = 4; - string publicDir = 5; + Exec run = 1; + Exec build = 2; + bool ignorePorts = 3; + DeploymentConfig.Target target = 4; + string publicDir = 5; } message ExtensionConfig { - bool isExtension = 1; - string extensionID = 2; - string buildCommand = 3; - string outputDirectory = 4; + bool isExtension = 1; + string extensionID = 2; + string buildCommand = 3; + string outputDirectory = 4; + string staticDirectory = 5; } -message NixConfig { - string channel = 1; -} +message NixConfig { string channel = 1; } message HostingConfig { - string route = 1; - string directory = 2; + string route = 1; + string directory = 2; } message AuthConfig { - bool pageEnabled = 1; - string pageTitle = 2; - string pageDescription = 3; - string pageColor = 4; - string pageImage = 5; - bool buttonEnabled = 6; + bool pageEnabled = 1; + string pageTitle = 2; + string pageDescription = 3; + string pageColor = 4; + string pageImage = 5; + bool buttonEnabled = 6; } message DotReplitInterp { - Exec command = 1; - bytes prompt = 2; + Exec command = 1; + bytes prompt = 2; } message DotReplitLanguage { - string pattern = 1; - string syntax = 2; - LanguageServerConfig languageServer = 3; + string pattern = 1; + string syntax = 2; + LanguageServerConfig languageServer = 3; } message LanguageServerConfig { - Exec startCommand = 1; - string configurationJson = 2; - string initializationOptionsJson = 3; + Exec startCommand = 1; + string configurationJson = 2; + string initializationOptionsJson = 3; } message DotReplitPackager { - Exec afterInstall = 1; - string language = 4; - DotReplitPackagerFeatures features = 5; - map env = 6; - repeated string ignoredPaths = 2; - repeated string ignoredPackages = 3; + Exec afterInstall = 1; + string language = 4; + DotReplitPackagerFeatures features = 5; + map env = 6; + repeated string ignoredPaths = 2; + repeated string ignoredPackages = 3; } message DotReplitPackagerFeatures { - bool packageSearch = 1; - bool guessImports = 2; - bool enabledForHosting = 3; + bool packageSearch = 1; + bool guessImports = 2; + bool enabledForHosting = 3; } -message DotReplitUnitTest { - string language = 1; -} +message DotReplitUnitTest { string language = 1; } message DebuggerConfig { - bool support = 1; - CompileConfig compile = 2; - DapConfig interactive = 3; - TimeTravelConfig timeTravel = 4; - string dapTransport = 5; - int64 dapConnectTimeout = 6; - DapIntegratedAdapterConfig dapIntegratedAdapter = 7; - Exec dapStartCommand = 8; - google.protobuf.Struct dapInitializeMessage = 9; - google.protobuf.Struct dapLaunchMessage = 10; + bool support = 1; + CompileConfig compile = 2; + DapConfig interactive = 3; + TimeTravelConfig timeTravel = 4; + string dapTransport = 5; + int64 dapConnectTimeout = 6; + DapIntegratedAdapterConfig dapIntegratedAdapter = 7; + Exec dapStartCommand = 8; + google.protobuf.Struct dapInitializeMessage = 9; + google.protobuf.Struct dapLaunchMessage = 10; } message CompileConfig { - Exec command = 1; - bool onlyMain = 2; - bool noFileArgs = 3; + Exec command = 1; + bool onlyMain = 2; + bool noFileArgs = 3; } message DapConfig { - string transport = 1; - int64 connectTimeout = 2; - DapIntegratedAdapterConfig integratedAdapter = 3; - Exec startCommand = 4; - google.protobuf.Struct initializeMessage = 5; - google.protobuf.Struct launchMessage = 6; + string transport = 1; + int64 connectTimeout = 2; + DapIntegratedAdapterConfig integratedAdapter = 3; + Exec startCommand = 4; + google.protobuf.Struct initializeMessage = 5; + google.protobuf.Struct launchMessage = 6; } message TimeTravelConfig { - Exec record = 1; - DapConfig debug = 2; + Exec record = 1; + DapConfig debug = 2; } -message DapIntegratedAdapterConfig { - string dapTcpAddress = 1; -} +message DapIntegratedAdapterConfig { string dapTcpAddress = 1; } -message ProxyGoingAway { -} +message ProxyGoingAway {} -message FirewallDenied { -} +message FirewallDenied {} message ReplLogMessage { - google.protobuf.Timestamp timestamp = 1; - string replId = 2; - string logLine = 3; - string userName = 4; + google.protobuf.Timestamp timestamp = 1; + string replId = 2; + string logLine = 3; + string userName = 4; } message UserEvent { - string eventName = 1; - google.protobuf.Struct eventData = 2; - int32 version = 3; + string eventName = 1; + google.protobuf.Struct eventData = 2; + int32 version = 3; } -message NixModulesGetRequest { -} +message NixModulesGetRequest {} -message NixModulesGetResponse { - repeated NixModule modules = 1; -} +message NixModulesGetResponse { repeated NixModule modules = 1; } message NixModule { - string id = 1; - string version = 2; - string name = 3; - string description = 4; - repeated RunOption runners = 5; - repeated DebuggerOption debuggers = 6; - repeated PackagerOption packagers = 7; - repeated LanguageServerOption languageServers = 8; - string buildType = 9; - repeated string resolutionPath = 10; - string resolvedId = 11; - string referencedId = 12; + string id = 1; + string version = 2; + string name = 3; + string description = 4; + repeated RunOption runners = 5; + repeated DebuggerOption debuggers = 6; + repeated PackagerOption packagers = 7; + repeated LanguageServerOption languageServers = 8; + string buildType = 9; + repeated string resolutionPath = 10; + string resolvedId = 11; + string referencedId = 12; + repeated FormatterOption formatters = 13; } -message NixModulesChanged { - repeated NixModule modules = 1; -} +message NixModulesChanged { repeated NixModule modules = 1; } -message NixModulesBuildRequest { -} +message NixModulesBuildRequest {} -message NixModulesGetRegistryRequest { -} +message NixModulesGetRegistryRequest {} message NixModulesGetRegistryResponse { - repeated NixModulesRegistryEntry modules = 1; - map autoUpgrade = 2; - map recommendUpgrade = 3; + repeated NixModulesRegistryEntry modules = 1; + map autoUpgrade = 2; + map recommendUpgrade = 3; } message NixModulesRegistryEntry { - string id = 1; - string name = 2; - string description = 3; - int32 version = 4; - string tag = 5; - repeated string tags = 6; - string commit = 7; - string path = 8; + string id = 1; + string name = 2; + string description = 3; + int32 version = 4; + string tag = 5; + repeated string tags = 6; + string commit = 7; + string path = 8; } message NixModulesUpgradeMapEntry { - string to = 1; - string changelog = 2; + string to = 1; + string changelog = 2; } -message ToolchainGetRequest { -} +message ToolchainGetRequest {} message ToolchainConfigs { - string entrypoint = 1; - repeated RunOption runs = 2; - repeated DebuggerOption debuggers = 3; - repeated LanguageServerOption languageServers = 4; - repeated PackagerOption packagers = 5; + string entrypoint = 1; + repeated RunOption runs = 2; + repeated DebuggerOption debuggers = 3; + repeated LanguageServerOption languageServers = 4; + repeated PackagerOption packagers = 5; + repeated FormatterOption formatters = 6; + bool disableInstallBeforeRun = 7; + bool disableGuessImports = 8; } -message ToolchainGetResponse { - ToolchainConfigs configs = 1; -} +message ToolchainGetResponse { ToolchainConfigs configs = 1; } -message ToolchainChanged { - ToolchainConfigs configs = 1; -} +message ToolchainChanged { ToolchainConfigs configs = 1; } message RunOption { - string id = 1; - string name = 2; - bool fileParam = 3; - string language = 4; - FileTypeAttrs fileTypeAttrs = 5; + string id = 1; + string name = 2; + bool fileParam = 3; + string language = 4; + FileTypeAttrs fileTypeAttrs = 5; + bool interpreter = 6; + bool optionalFileParam = 7; } message DebuggerOption { - string id = 1; - string name = 2; - bool fileParam = 3; - string language = 4; - FileTypeAttrs fileTypeAttrs = 5; + string id = 1; + string name = 2; + bool fileParam = 3; + string language = 4; + FileTypeAttrs fileTypeAttrs = 5; } message LanguageServerOption { - string id = 1; - string name = 2; - string language = 3; - FileTypeAttrs fileTypeAttrs = 4; - LanguageServerConfig config = 5; + string id = 1; + string name = 2; + string language = 3; + FileTypeAttrs fileTypeAttrs = 4; + LanguageServerConfig config = 5; } message FileTypeAttrs { - repeated string extensions = 1; - repeated string files = 2; - string filePattern = 3; + repeated string extensions = 1; + repeated string files = 2; + string filePattern = 3; } message PackagerOption { - string id = 1; - string name = 2; - string language = 3; - repeated string packagerFiles = 4; - bool enabledForHosting = 5; - bool packageSearch = 6; - bool guessImports = 7; + string id = 1; + string name = 2; + string language = 3; + repeated string packagerFiles = 4; + bool enabledForHosting = 5; + bool packageSearch = 6; + bool guessImports = 7; +} + +message FormatterOption { + string id = 1; + string name = 2; + Exec startCommand = 3; + FileTypeAttrs fileTypeAttrs = 4; } message ReplDomainDoubleDash { - string user = 1; - string slug = 2; - string suffix = 3; + string user = 1; + string slug = 2; + string suffix = 3; } message ReplDomainDots { - string user = 1; - string slug = 2; - string suffix = 3; + string user = 1; + string slug = 2; + string suffix = 3; } message ReplDomainSingleDomain { - string user = 1; - string suffix = 2; + string user = 1; + string suffix = 2; } message ReplDomainId { - string id = 1; - string suffix = 2; + string id = 1; + string suffix = 2; } message ReplDomain { - oneof kind { - string custom = 1; - ReplDomainId id = 2; - ReplDomainDoubleDash doubleDash = 3; - ReplDomainDots dots = 4; - ReplDomainSingleDomain singleDomain = 5; - } + oneof kind { + string custom = 1; + ReplDomainId id = 2; + ReplDomainDoubleDash doubleDash = 3; + ReplDomainDots dots = 4; + ReplDomainSingleDomain singleDomain = 5; + } +} + +message OutputBlockStartEvent { + enum ExecutionMode { + Run = 0; + Interpret = 1; + } + + OutputBlockStartEvent.ExecutionMode executionMode = 1; + google.protobuf.Timestamp measureStartTime = 2; +} + +message OutputBlockEndEvent { + sint32 exitCode = 1; + google.protobuf.Timestamp measureEndTime = 2; +} + +message RulesConfig { FormatterRules formatter = 1; } + +message FormatterRules { + repeated FormatterConfigWithPattern patterns = 1; + map fileExtensions = 2; + map languages = 3; +} + +message FormatterConfig { string id = 1; } + +message FormatterConfigWithPattern { + string id = 1; + string pattern = 2; } message ReplToken { - message ClassroomMetadata { - string id = 1; - string language = 2; - } - - message ReplID { - string id = 1; - string sourceRepl = 2; - } - - enum WireFormat { - PROTOBUF = 0; - JSON = 1; - } - - message Presenced { - uint32 bearerID = 1; - string bearerName = 2; - } - - google.protobuf.Timestamp iat = 1; - google.protobuf.Timestamp exp = 2; - string salt = 3; - string cluster = 4; - repl.Persistence persistence = 6; - repl.ResourceLimits resourceLimits = 10; - repl.ResourceLimits interactiveResourceLimits = 17; - ReplToken.WireFormat format = 12; - ReplToken.Presenced presenced = 13; - repeated string flags = 14; - repl.Permissions permissions = 15; - repeated features.Feature features = 16; - repl.BuildInfo buildInfo = 18; - oneof metadata { - repl.Repl repl = 7; - ReplToken.ReplID id = 8; - ReplToken.ClassroomMetadata classroom = 9; - } + message ClassroomMetadata { + string id = 1; + string language = 2; + } + + message ReplID { + string id = 1; + string sourceRepl = 2; + } + + enum WireFormat { + PROTOBUF = 0; + JSON = 1; + PID2 = 2; + } + + message Presenced { + uint32 bearerID = 1; + string bearerName = 2; + } + + google.protobuf.Timestamp iat = 1; + google.protobuf.Timestamp exp = 2; + string salt = 3; + string cluster = 4; + repl.Persistence persistence = 6; + repl.ResourceLimits resourceLimits = 10; + repl.ResourceLimits interactiveResourceLimits = 17; + ReplToken.WireFormat format = 12; + ReplToken.Presenced presenced = 13; + repeated string flags = 14; + repl.Permissions permissions = 15; + repeated features.Feature features = 16; + repl.BuildInfo buildInfo = 18; + oneof metadata { + repl.Repl repl = 7; + ReplToken.ReplID id = 8; + ReplToken.ClassroomMetadata classroom = 9; + } } message TLSCertificate { - string domain = 1; - bytes cert = 2; + string domain = 1; + bytes cert = 2; } message ReplTransfer { - repl.Repl repl = 1; - repl.ResourceLimits replLimits = 2; - repl.ResourceLimits userLimits = 3; - repeated string customDomains = 4; - repeated TLSCertificate certificates = 5; - repeated string flags = 6; - repl.Metadata metadata = 7; + repl.Repl repl = 1; + repl.ResourceLimits replLimits = 2; + repl.ResourceLimits userLimits = 3; + repeated string customDomains = 4; + repeated TLSCertificate certificates = 5; + repeated string flags = 6; + repl.Metadata metadata = 7; } -message AllowReplRequest { - ReplTransfer replTransfer = 1; -} +message AllowReplRequest { ReplTransfer replTransfer = 1; } message ClusterMetadata { - string id = 1; - string conmanURL = 2; - string gurl = 3; - string proxy = 5; - string continent = 7; + string id = 1; + string conmanURL = 2; + string gurl = 3; + string proxy = 5; + string continent = 7; } message EvictReplRequest { - ClusterMetadata clusterMetadata = 1; - string token = 2; - string user = 3; - string slug = 4; + ClusterMetadata clusterMetadata = 1; + string token = 2; + string user = 3; + string slug = 4; } -message EvictReplResponse { - ReplTransfer replTransfer = 1; -} +message EvictReplResponse { ReplTransfer replTransfer = 1; } enum TokenVersion { - BARE_REPL_TOKEN = 0; - TYPE_AWARE_TOKEN = 1; + BARE_REPL_TOKEN = 0; + TYPE_AWARE_TOKEN = 1; } message GovalSigningAuthority { - TokenVersion version = 3; - string issuer = 4; - oneof cert { - string keyId = 1; - string signedCert = 2; - } + TokenVersion version = 3; + string issuer = 4; + oneof cert { + string keyId = 1; + string signedCert = 2; + } } enum FlagClaim { - MINT_GOVAL_TOKEN = 0; - SIGN_INTERMEDIATE_CERT = 1; - IDENTITY = 5; - GHOSTWRITER = 6; - RENEW_IDENTITY = 7; - RENEW_KV = 8; - ANY_REPLID = 2; - ANY_USER = 3; - ANY_CLUSTER = 4; + MINT_GOVAL_TOKEN = 0; + SIGN_INTERMEDIATE_CERT = 1; + IDENTITY = 5; + GHOSTWRITER = 6; + RENEW_IDENTITY = 7; + RENEW_KV = 8; + DEPLOYMENTS = 10; + ANY_REPLID = 2; + ANY_USER = 3; + ANY_USER_ID = 11; + ANY_CLUSTER = 4; + ANY_SUBCLUSTER = 9; } message CertificateClaim { - oneof claim { - string replid = 1; - string user = 2; - string cluster = 4; - FlagClaim flag = 3; - } + oneof claim { + string replid = 1; + string user = 2; + int64 userId = 7; + string cluster = 4; + string subcluster = 5; + bool deployment = 6; + FlagClaim flag = 3; + } } message GovalCert { - google.protobuf.Timestamp iat = 1; - google.protobuf.Timestamp exp = 2; - repeated CertificateClaim claims = 3; - string publicKey = 4; + google.protobuf.Timestamp iat = 1; + google.protobuf.Timestamp exp = 2; + repeated CertificateClaim claims = 3; + string publicKey = 4; } message GovalToken { - google.protobuf.Timestamp iat = 1; - google.protobuf.Timestamp exp = 2; - string replid = 3; - oneof Token { - ReplToken replToken = 4; - GovalReplIdentity replIdentity = 5; - } + google.protobuf.Timestamp iat = 1; + google.protobuf.Timestamp exp = 2; + string replid = 3; + oneof Token { + ReplToken replToken = 4; + GovalReplIdentity replIdentity = 5; + } } message GovalReplIdentity { - string replid = 1; - string user = 2; - string slug = 3; - string aud = 4; - bool ephemeral = 5; - string originReplid = 6; - int64 userId = 7; - repl.BuildInfo buildInfo = 8; - bool isTeam = 9; - repeated string roles = 10; + string replid = 1; + string user = 2; + string slug = 3; + string aud = 4; + bool ephemeral = 5; + string originReplid = 6; + int64 userId = 7; + repl.BuildInfo buildInfo = 8; + bool isTeam = 9; + repeated string roles = 10; + oneof runtime { + ReplRuntimeInteractive interactive = 11; + ReplRuntimeHosting hosting = 13; + ReplRuntimeDeployment deployment = 12; + } } -message lore { - message LoreCommand { - oneof command { - lore.ClusterTransfer clusterTransfer = 1; - lore.SoftTakedown softTakedown = 2; - lore.Takedown takedown = 6; - lore.GovalCommand govalCommand = 3; - lore.MultiGovalCommand multiGovalCommand = 5; - lore.Restore restore = 4; - } - } - - message ClusterTransfer { - string replId = 1; - string user = 2; - string transferId = 4; - oneof location { - string newClusterId = 3; - string newContinentId = 5; - } - } - - message SoftTakedown { - string replId = 1; - string softTakedownId = 2; - } - - message Takedown { - string replId = 1; - } - - message GovalCommand { - oneof command { - repl.Metadata updateMetadata = 1; - lore.PartialUpdateMetadata partialUpdateMetadata = 2; - lore.KillRepl killRepl = 3; - lore.UpdateSourceRepl updateSourceRepl = 4; - lore.UpdateReplFlags updateReplFlags = 5; - lore.SoftTakedown softTakedown = 6; - lore.Takedown takedown = 7; - } - } - - message PartialUpdateMetadata { - google.protobuf.FieldMask fieldMask = 1; - repl.Metadata updateMetadata = 2; - } - - message MultiGovalCommand { - string replId = 1; - repeated lore.GovalCommand govalCommands = 2; - } - - message KillRepl { - string replId = 1; - } - - message Restore { - string replId = 1; - string restoreReplId = 2; - } - - message UpdateSourceRepl { - string replId = 1; - string sourceReplId = 2; - } - - message UpdateReplFlags { - string replId = 1; - repeated string flags = 2; - } +message ReplRuntimeInteractive { + string cluster = 1; + string subcluster = 2; +} +message ReplRuntimeHosting { + string cluster = 1; + string subcluster = 2; +} + +message ReplRuntimeDeployment {} + +message lore { + message LoreCommand { + oneof command { + lore.ClusterTransfer clusterTransfer = 1; + lore.SoftTakedown softTakedown = 2; + lore.Takedown takedown = 6; + lore.GovalCommand govalCommand = 3; + lore.MultiGovalCommand multiGovalCommand = 5; + lore.Restore restore = 4; + } + } + + message ClusterTransfer { + string replId = 1; + string user = 2; + string transferId = 4; + oneof location { + string newClusterId = 3; + string newContinentId = 5; + } + } + + message SoftTakedown { + string replId = 1; + string softTakedownId = 2; + } + + message Takedown { string replId = 1; } + + message GovalCommand { + oneof command { + repl.Metadata updateMetadata = 1; + lore.PartialUpdateMetadata partialUpdateMetadata = 2; + lore.KillRepl killRepl = 3; + lore.UpdateSourceRepl updateSourceRepl = 4; + lore.UpdateReplFlags updateReplFlags = 5; + lore.SoftTakedown softTakedown = 6; + lore.Takedown takedown = 7; + } + } + + message PartialUpdateMetadata { + google.protobuf.FieldMask fieldMask = 1; + repl.Metadata updateMetadata = 2; + } + + message MultiGovalCommand { + string replId = 1; + repeated lore.GovalCommand govalCommands = 2; + } + + message KillRepl { string replId = 1; } + + message Restore { string replId = 1; } + + message UpdateSourceRepl { + string replId = 1; + string sourceReplId = 2; + } + + message UpdateReplFlags { + string replId = 1; + repeated string flags = 2; + } } message features { - message Gpu { - } + message Gpu {} - message Boosted { - } + message Boosted {} - message Feature { - bool required = 3; - oneof feature { - features.Gpu gpu = 1; - features.Boosted boosted = 2; - } - } + message Backpack {} + message Feature { + bool required = 3; + oneof feature { + features.Gpu gpu = 1; + features.Boosted boosted = 2; + features.Backpack backpack = 4; + } + } } message repl { - message Buckets { - string snapshots = 1; - string metadata = 2; - string diskBlocks = 3; - } - - message Repl { - string id = 1; - string language = 2; - string bucket = 3; - string slug = 4; - string user = 5; - string sourceRepl = 6; - string database = 7; - repl.Buckets buckets = 8; - repl.UserId userId = 9; - bool isTeam = 10; - repeated string roles = 11; - } - - enum Environment { - DEVELOPMENT = 0; - PRODUCTION = 1; - } - - message UserId { - int64 id = 1; - repl.Environment environment = 2; - } - - message ResourceLimits { - enum Cachability { - NONE = 0; - USER = 1; - REPL = 2; - } - - bool net = 1; - int64 memory = 2; - double threads = 3; - double shares = 4; - int64 disk = 5; - repl.ResourceLimits.Cachability cache = 6; - bool restrictNetwork = 7; - bool preventWakeup = 8; - } - - message Permissions { - bool toggleAlwaysOn = 1; - } - - enum Persistence { - PERSISTENT = 0; - EPHEMERAL = 1; - NONE = 2; - READ_ONLY = 3; - } - - message Metadata { - repl.Repl repl = 7; - repl.ResourceLimits resourceLimits = 10; - repl.ResourceLimits interactiveResourceLimits = 17; - repl.Persistence persistence = 6; - repeated string flags = 14; - repl.Permissions permissions = 15; - repeated features.Feature features = 16; - repl.BuildInfo buildInfo = 18; - } - - message BuildInfo { - string deploymentId = 1; - string url = 2; - string buildId = 3; - string machineTier = 4; - } - -} - -message PrivateReplsPowerup { - bool enabled = 1; -} - -message GhostwriterPowerup { - bool enabled = 1; -} - -message ConnectivityPowerup { - bool enabled = 1; -} + message Buckets { + string snapshots = 1; + string metadata = 2; + string diskBlocks = 3; + } + + message Repl { + string id = 1; + string language = 2; + string bucket = 3; + string slug = 4; + string user = 5; + string sourceRepl = 6; + string database = 7; + repl.Buckets buckets = 8; + repl.UserId userId = 9; + bool isTeam = 10; + repeated string roles = 11; + string logFields = 13; + } + + enum Environment { + DEVELOPMENT = 0; + PRODUCTION = 1; + } + + message UserId { + int64 id = 1; + repl.Environment environment = 2; + } + + message ResourceLimits { + enum Cachability { + NONE = 0; + USER = 1; + REPL = 2; + } + + bool net = 1; + int64 memory = 2; + double threads = 3; + double shares = 4; + int64 disk = 5; + int64 minimumDisk = 10; + int64 scratchDisk = 9; + repl.ResourceLimits.Cachability cache = 6; + bool restrictNetwork = 7; + bool preventWakeup = 8; + } + + message Permissions { bool toggleAlwaysOn = 1; } + + enum Persistence { + PERSISTENT = 0; + EPHEMERAL = 1; + NONE = 2; + READ_ONLY = 3; + } + + message Metadata { + repl.Repl repl = 7; + repl.ResourceLimits resourceLimits = 10; + repl.ResourceLimits interactiveResourceLimits = 17; + repl.Persistence persistence = 6; + repeated string flags = 14; + repl.Permissions permissions = 15; + repeated features.Feature features = 16; + repl.BuildInfo buildInfo = 18; + } + + message BuildInfo { + string deploymentId = 1; + string url = 2; + string buildId = 3; + string machineTier = 4; + } +} + +message PrivateReplsPowerup { bool enabled = 1; } + +message GhostwriterPowerup { bool enabled = 1; } + +message ConnectivityPowerup { bool enabled = 1; } message PowerUp { - google.protobuf.Timestamp expiresAt = 1; - oneof powerup { - PrivateReplsPowerup private = 10; - GhostwriterPowerup ghostwriter = 11; - ConnectivityPowerup connectivity = 12; - } + google.protobuf.Timestamp expiresAt = 1; + oneof powerup { + PrivateReplsPowerup private = 10; + GhostwriterPowerup ghostwriter = 11; + ConnectivityPowerup connectivity = 12; + } } message UserPowerUps { - uint32 userId = 1; - string username = 2; - repeated PowerUp powerups = 3; + uint32 userId = 1; + string username = 2; + repeated PowerUp powerups = 3; } - diff --git a/services/src/lib.rs b/services/src/lib.rs index f74c7be..805a052 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -1,9 +1,11 @@ mod chat; mod gcsfiles; mod ot; +mod output; mod presence; mod snapshot; mod stub; +mod toolchain; mod traits; mod types; @@ -12,6 +14,9 @@ use anyhow::Result; use log::as_display; use log::error; use std::collections::HashMap; +use std::sync::Arc; +use tokio::sync::RwLock; +use types::config::dotreplit::DotReplit; pub use types::*; pub struct Channel { @@ -25,6 +30,7 @@ impl Channel { id: i32, service: String, name: Option, + dotreplit: Arc>, sender: tokio::sync::mpsc::UnboundedSender, ) -> Result { let channel: Box = match service.as_str() { @@ -33,6 +39,8 @@ impl Channel { "presence" => Box::new(presence::Presence::new()), "ot" => Box::new(ot::OT::new(sender.clone()).await?), "snapshot" => Box::new(snapshot::Snapshot {}), + "output" => Box::new(output::Output::new().await), + "toolchain" => Box::new(toolchain::Toolchain {}), "null" => Box::new(stub::Stub {}), // This channel never does anything "open" => Box::new(stub::Stub {}), // Stub until infra is set up to handle this "git" => Box::new(stub::Stub {}), // Stub until replspace api is fixed @@ -46,6 +54,7 @@ impl Channel { clients: HashMap::new(), sessions: HashMap::new(), sender, + dotreplit, }; Ok(Channel { @@ -62,7 +71,9 @@ impl Channel { } ChannelMessage::Detach(session) => self.detach(session).await, ChannelMessage::IPC(ipc) => self.message(ipc.command, ipc.session).await, - ChannelMessage::ProcessDead(_, _) => todo!(), + ChannelMessage::ProcessDead(exit_code) => { + self._inner.proccess_died(&self.info, exit_code).await + } ChannelMessage::CmdDead(_) => todo!(), ChannelMessage::Replspace(_, _) => todo!(), ChannelMessage::Shutdown => match self._inner.shutdown(&self.info).await { @@ -132,5 +143,14 @@ impl Channel { } pub static IMPLEMENTED_SERVICES: &[&str] = &[ - "chat", "gcsfiles", "presence", "ot", "snapshot", "null", "git", "open", + "chat", + "gcsfiles", + "presence", + "ot", + "snapshot", + "null", + "git", + "open", + "output", + "toolchain", ]; diff --git a/services/src/ot.rs b/services/src/ot.rs index 98cd1f4..7954822 100644 --- a/services/src/ot.rs +++ b/services/src/ot.rs @@ -22,11 +22,6 @@ use log::{as_debug, debug, error, trace, warn}; use similar::TextDiff; use tokio::fs; -enum LoopControl { - Cont(Result<()>), - Break, -} - impl OT { pub async fn new( sender: tokio::sync::mpsc::UnboundedSender, @@ -309,7 +304,7 @@ impl traits::Service for OT { } async fn fsevent(&mut self, info: &super::types::ChannelInfo, event: FSEvent) -> Result<()> { - trace!(event = as_debug!(event), file_path = self.path; "oooh event"); + trace!(event = as_debug!(event), file_path = self.path; "fs event"); match event { FSEvent::Modify(path) => { trace!(condition = (path == self.path), path = path, file_path = self.path; "Conditional time"); @@ -329,6 +324,7 @@ impl traits::Service for OT { let ops = diff(self.contents.to_string(), new_contents.clone()); self.contents = new_contents.into(); + self.crc32 = new_crc32; let committed = Some(prost_types::Timestamp { seconds: SystemTime::now() @@ -373,8 +369,8 @@ impl traits::Service for OT { &mut self, _info: &super::types::ChannelInfo, _client: ClientInfo, - session: i32, - sender: tokio::sync::mpsc::UnboundedSender, + _session: i32, + _sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { if &self.path == "" { let mut cmd = goval::Command::default(); diff --git a/services/src/output.rs b/services/src/output.rs new file mode 100644 index 0000000..da9ab00 --- /dev/null +++ b/services/src/output.rs @@ -0,0 +1,188 @@ +pub struct Output { + pty: Option, + start_time: Option, +} +use std::{ + sync::Arc, + time::{SystemTime, UNIX_EPOCH}, + vec, +}; + +use async_trait::async_trait; +use log::{as_debug, debug, warn}; +use prost_types::Timestamp; +use tokio::sync::RwLock; + +use super::traits; +use super::types::pty::Pty; +use crate::{ClientInfo, IPCMessage}; +use anyhow::{format_err, Result}; + +#[async_trait] +impl traits::Service for Output { + async fn attach( + &mut self, + info: &super::types::ChannelInfo, + _client: ClientInfo, + session: i32, + sender: tokio::sync::mpsc::UnboundedSender, + ) -> Result> { + if let Some(pty) = &mut self.pty { + let mut new_frame = goval::Command::default(); + + let event = goval::OutputBlockStartEvent { + execution_mode: goval::output_block_start_event::ExecutionMode::Run.into(), + measure_start_time: Some(Timestamp { + seconds: self.start_time.unwrap_or(0), + nanos: 0, + }), + }; + + new_frame.body = Some(goval::command::Body::OutputBlockStartEvent(event)); + info.send(new_frame, crate::SendSessions::Only(session)) + .await?; + + pty.session_join(session, sender).await?; + } + + let mut status = goval::Command::default(); + let state; + if self.start_time.is_some() { + state = goval::State::Running + } else { + state = goval::State::Stopped + } + + status.body = Some(goval::command::Body::State(state.into())); + Ok(Some(status)) + } + + async fn detach(&mut self, _info: &super::types::ChannelInfo, session: i32) -> Result<()> { + if let Some(pty) = &mut self.pty { + pty.session_leave(session).await?; + } + Ok(()) + } + + async fn message( + &mut self, + info: &super::types::ChannelInfo, + message: goval::Command, + _session: i32, + ) -> Result> { + let body = match message.body.clone() { + None => return Err(format_err!("Expected command body")), + Some(body) => body, + }; + + match body { + goval::command::Body::RunMain(_) => { + let time = SystemTime::now(); + let now = time.duration_since(UNIX_EPOCH)?.as_secs() as i64; + self.start_time = Some(now); + let mut cmd = vec![ + "echo".to_string(), + "Please configure a run command in `.replit`".to_string(), + ]; + if let Some(run) = &info.dotreplit.read().await.run { + if let Some(args) = &run.args { + cmd = args.clone() + } + } + + self.pty = Some( + Pty::start( + cmd, + info.id, + Arc::new(RwLock::new(info.clients.clone())), + info.sender.clone(), + None, + ) + .await?, + ); + + let mut new_frame = goval::Command::default(); + + let event = goval::OutputBlockStartEvent { + execution_mode: goval::output_block_start_event::ExecutionMode::Run.into(), + measure_start_time: Some(Timestamp { + seconds: now, + nanos: 0, + }), + }; + + new_frame.body = Some(goval::command::Body::OutputBlockStartEvent(event)); + info.send(new_frame, crate::SendSessions::Everyone).await?; + + let mut status = goval::Command::default(); + + status.body = Some(goval::command::Body::State(goval::State::Running.into())); + info.send(status, crate::SendSessions::Everyone).await?; + } + goval::command::Body::Clear(_) => { + if let Some(pty) = &mut self.pty { + pty.cancel().await?; + } else { + warn!("Client tried to stop an already stopped pty") + } + } + goval::command::Body::Input(msg) => { + if let Some(pty) = &mut self.pty { + pty.write(msg)?; + } + } + goval::command::Body::ResizeTerm(_) => {} + _ => { + debug!(msg = as_debug!(message); "New message"); + } + } + Ok(None) + } + + async fn proccess_died( + &mut self, + info: &super::types::ChannelInfo, + exit_code: i32, + ) -> Result<()> { + self.pty = None; + self.start_time = None; + + let time = SystemTime::now(); + let now = time.duration_since(UNIX_EPOCH)?.as_secs() as i64; + + let mut end_frame = goval::Command::default(); + + let event = goval::OutputBlockEndEvent { + exit_code, + measure_end_time: Some(Timestamp { + seconds: now, + nanos: 0, + }), + }; + + end_frame.body = Some(goval::command::Body::OutputBlockEndEvent(event)); + info.send(end_frame, crate::SendSessions::Everyone).await?; + + if exit_code != 0 { + let mut error = goval::Command::default(); + error.body = Some(goval::command::Body::Error(format!( + "exit code {exit_code}" + ))); + info.send(error, crate::SendSessions::Everyone).await?; + } + + let mut status = goval::Command::default(); + status.body = Some(goval::command::Body::State(goval::State::Stopped.into())); + info.send(status, crate::SendSessions::Everyone).await?; + Ok(()) + } +} + +impl Output { + pub async fn new() -> Output { + Output { + pty: None, + start_time: None, + } + } +} diff --git a/services/src/toolchain.rs b/services/src/toolchain.rs new file mode 100644 index 0000000..a5559f6 --- /dev/null +++ b/services/src/toolchain.rs @@ -0,0 +1,55 @@ +pub struct Toolchain {} +use super::traits; +use async_trait::async_trait; +use log::{as_debug, debug}; + +use anyhow::{format_err, Result}; + +#[async_trait] +impl traits::Service for Toolchain { + async fn message( + &mut self, + _info: &super::types::ChannelInfo, // TODO: use this to give real toolchain info + message: goval::Command, + _session: i32, + ) -> Result> { + let body = match message.body.clone() { + None => return Err(format_err!("Expected command body")), + Some(body) => body, + }; + match body { + goval::command::Body::NixModulesGetRequest(_) => { + let mut modules = goval::Command::default(); + + modules.body = Some(goval::command::Body::NixModulesGetResponse( + goval::NixModulesGetResponse::default(), + )); + + Ok(Some(modules)) + } + goval::command::Body::ToolchainGetRequest(_) => { + let mut toolchain = goval::Command::default(); + + let mut inner = goval::ToolchainGetResponse::default(); + let mut configs = goval::ToolchainConfigs::default(); + configs.runs = vec![goval::RunOption { + id: "homeval/test".into(), + name: "Test".into(), + file_param: false, + language: "idk".into(), + file_type_attrs: None, + interpreter: false, + optional_file_param: false, + }]; + inner.configs = Some(configs); + toolchain.body = Some(goval::command::Body::ToolchainGetResponse(inner)); + + Ok(Some(toolchain)) + } + _ => { + debug!(msg = as_debug!(message); "Unrecognized command :/"); + Ok(None) + } + } + } +} diff --git a/services/src/traits.rs b/services/src/traits.rs index 87bb215..13ba214 100644 --- a/services/src/traits.rs +++ b/services/src/traits.rs @@ -21,6 +21,14 @@ pub(crate) trait Service { Ok(None) } + async fn proccess_died( + &mut self, + _info: &super::types::ChannelInfo, + _exit_code: i32, + ) -> Result<()> { + Ok(()) + } + async fn fsevent(&mut self, _info: &super::types::ChannelInfo, _event: FSEvent) -> Result<()> { Ok(()) } diff --git a/services/src/types/channel_info.rs b/services/src/types/channel_info.rs index c87c7ce..9de3793 100644 --- a/services/src/types/channel_info.rs +++ b/services/src/types/channel_info.rs @@ -1,8 +1,12 @@ use std::collections::HashMap; +use std::sync::Arc; use anyhow::Result; use goval; use log::error; +use tokio::sync::RwLock; + +use crate::config::dotreplit::DotReplit; use super::client::ClientInfo; use super::messaging::IPCMessage; @@ -20,6 +24,7 @@ pub struct ChannelInfo { pub name: Option, pub sessions: HashMap, pub sender: tokio::sync::mpsc::UnboundedSender, + pub dotreplit: Arc>, } impl ChannelInfo { diff --git a/src/config.rs b/services/src/types/config.rs similarity index 100% rename from src/config.rs rename to services/src/types/config.rs diff --git a/services/src/types/fs_watcher.rs b/services/src/types/fs_watcher.rs index 955d450..e94edfa 100644 --- a/services/src/types/fs_watcher.rs +++ b/services/src/types/fs_watcher.rs @@ -9,7 +9,6 @@ use serde::Serialize; use anyhow::Result; use std::{path::Path, time::Duration}; -use tokio::sync::broadcast; use crate::ChannelMessage; diff --git a/services/src/types/messaging.rs b/services/src/types/messaging.rs index 37e0178..0e30662 100644 --- a/services/src/types/messaging.rs +++ b/services/src/types/messaging.rs @@ -26,7 +26,7 @@ pub enum ChannelMessage { tokio::sync::mpsc::UnboundedSender, ), Detach(i32), - ProcessDead(u32, i32), + ProcessDead(i32), CmdDead(i32), FSEvent(super::FSEvent), Replspace(i32, ReplspaceMessage), // session, message diff --git a/services/src/types/mod.rs b/services/src/types/mod.rs index 1e84859..7be0526 100644 --- a/services/src/types/mod.rs +++ b/services/src/types/mod.rs @@ -13,4 +13,6 @@ pub use fs_watcher::{FSEvent, FSWatcher}; pub mod service; pub use service::ServiceMetadata; -// pub mod pty; +pub mod pty; + +pub mod config; diff --git a/services/src/types/pty.rs b/services/src/types/pty.rs index c3899f9..24ca9de 100644 --- a/services/src/types/pty.rs +++ b/services/src/types/pty.rs @@ -1,21 +1,20 @@ -use futures_util::{future::abortable, stream::AbortHandle}; -use log::{error, warn}; -use portable_pty::PtySize; +// use futures_util::{future::abortable, stream::AbortHandle}; +use log::{as_display, as_error, error}; +use portable_pty::{Child, PtySize}; use std::{ collections::{HashMap, VecDeque}, - hash::Hash, io::{Error, ErrorKind, Write}, - sync::Arc, + sync::{atomic::AtomicBool, Arc}, }; +use crate::ChannelMessage; + use super::IPCMessage; use anyhow::{format_err, Result}; use tokio::sync::{Mutex, RwLock}; // use deno_core::{error::AnyError, op, OpDecl}; -use super::ChannelMessage; - // static PTY_CANCELLATION_MAP: LazyLock>> = // LazyLock::new(|| RwLock::new(HashMap::new())); // static PTY_SESSION_MAP: LazyLock>>> = @@ -24,8 +23,12 @@ use super::ChannelMessage; struct PtyWriter { channel: i32, sessions: Arc>>>, + cancelled: Arc, + scrollback: Arc>, } +static MAX_SCROLLBACK: usize = 10_000; + impl Write for PtyWriter { fn write(&mut self, buf: &[u8]) -> std::io::Result { let mut cmd = goval::Command::default(); @@ -39,10 +42,28 @@ impl Write for PtyWriter { } } - cmd.body = Some(goval::command::Body::Output(output)); + cmd.body = Some(goval::command::Body::Output(output.clone())); cmd.channel = self.channel; + if self.cancelled.load(std::sync::atomic::Ordering::SeqCst) { + return Err(std::io::Error::new(ErrorKind::Other, "cancelled")); + } + + let mut scrollback = self.scrollback.blocking_write(); + *scrollback += &output; + let scrollback_len = scrollback.len(); + if scrollback_len > MAX_SCROLLBACK { + *scrollback = scrollback + .split_at(scrollback_len - MAX_SCROLLBACK) + .1 + .to_string(); + } + drop(scrollback); + let sessions = self.sessions.blocking_read(); + if self.cancelled.load(std::sync::atomic::Ordering::SeqCst) { + return Err(std::io::Error::new(ErrorKind::Other, "cancelled")); + } for (session, sender) in sessions.iter() { let mut to_send = cmd.clone(); @@ -67,9 +88,13 @@ impl Write for PtyWriter { } } -struct Pty { +pub struct Pty { channel: i32, - sessions: Arc>>>, + pub sessions: Arc>>>, + writer: Box, + cancelled: Arc, + child_lock: Arc>>, + scrollback: Arc>, } impl Pty { @@ -77,9 +102,9 @@ impl Pty { _args: Vec, channel: i32, sessions: Arc>>>, + contact: tokio::sync::mpsc::UnboundedSender, _env: Option>, ) -> Result { - let pty = Pty { channel, sessions }; let env = match _env { Some(env) => env, None => HashMap::new(), @@ -117,228 +142,140 @@ impl Pty { // TODO: recode checkpoint let mut reader = pair.master.try_clone_reader()?; - let mut writer = pair.master.take_writer()?; - - let pty_id = child.process_id().expect("Missing process id????"); + let writer = pair.master.take_writer()?; + // let pty_id = child.process_id().expect("Missing process id????"); let child_lock = Arc::new(Mutex::new(child)); let child_lock_reaper = child_lock.clone(); + let cancelled = Arc::new(AtomicBool::new(false)); + let scrollback = Arc::new(RwLock::new(String::new())); + let mut pty_writer = PtyWriter { + channel, + sessions: sessions.clone(), + cancelled: cancelled.clone(), + scrollback: scrollback.clone(), + }; + + let contact_clone = contact.clone(); tokio::task::spawn(async move { - if let Err(err) = tokio::task::spawn_blocking(move || { - std::io::copy(&mut reader, &mut PtyWriter { channel, sessions }) + match tokio::task::spawn(async move { + if let Err(err) = + tokio::task::spawn_blocking(move || std::io::copy(&mut reader, &mut pty_writer)) + .await + { + error!("Error occurred copying from pty to channels: {}", err); + }; + + // let _read = crate::CHANNEL_MESSAGES.read().await; + // if !_read.contains_key(&channel) { + // return Err(format_err!("Owning channel")); + // } + + let exit_code; + + if let Some(code) = child_lock_reaper.lock().await.try_wait()? { + exit_code = code.exit_code() as i32; + } else { + exit_code = 0; + } + + // let queue = _read.get(&channel).unwrap().clone(); + // drop(_read); + contact_clone.send(ChannelMessage::ProcessDead(exit_code))?; + + Ok::<(), anyhow::Error>(()) }) .await { - error!("Error occurred copying from pty to channels: {}", err); - }; - - // let _read = crate::CHANNEL_MESSAGES.read().await; - // if !_read.contains_key(&channel) { - // return Err(format_err!("Owning channel")); - // } - - // let exit_code; - - // if let Some(code) = child_lock_reaper.lock().await.try_wait()? { - // exit_code = code.exit_code() as i32; - // } else {s - // exit_code = 0; - // } - - // let queue = _read.get(&channel).unwrap().clone(); - // drop(_read); - // queue.push(ChannelMessage::ProcessDead(pty_id, exit_code)); - Ok(()) - }); - - tokio::spawn(async move { - match task.await { - Ok(err) => { - error!("Error occurred while passing writes to pty: {}", err) - } - Err(_) => { - let mut child = child_lock.lock().await; - match child.kill() { - Ok(_) => {} - Err(err) => { - warn!("Failed to kill pty child: {}", err) - } + Ok(res) => match res { + Ok(_) => {} + Err(err) => { + error!(err = as_display!(err); "PTY child death alert error"); } - drop(child); + }, + Err(err) => { + error!(err = as_error!(err); "Join error in pty"); } } }); + // tokio::spawn(async move { + // match task.await { + // Ok(err) => { + // error!("Error occurred while passing writes to pty: {}", err) + // } + // Err(_) => { + // let mut child = child_lock.lock().await; + // match child.kill() { + // Ok(_) => {} + // Err(err) => { + // warn!("Failed to kill pty child: {}", err) + // } + // } + // drop(child); + // } + // } + // }); + + let pty = Pty { + channel, + sessions, + writer, + cancelled, + child_lock, + scrollback, + }; Ok(pty) } -} - -async fn op_register_pty( - _args: Vec, - channel: i32, - sessions: Option>, - _env: Option>, -) -> Result { - let mut env = crate::CHILD_PROCS_ENV_BASE.read().await.clone(); - if let Some(env_vars) = _env { - env.extend(env_vars); + pub async fn cancel(&mut self) -> Result<()> { + self.cancelled + .store(true, std::sync::atomic::Ordering::SeqCst); + self.child_lock.lock().await.kill()?; + Ok(()) } - let pty_system = portable_pty::native_pty_system(); - - // Create a new pty - let pair = pty_system.openpty(PtySize { - rows: 24, - cols: 80, - // Not all systems support pixel_width, pixel_height, - // but it is good practice to set it to something - // that matches the size of the selected font. That - // is more complex than can be shown here in this - // brief example though! - pixel_width: 0, - pixel_height: 0, - })?; - - // Spawn a shell into the pty - let mut cmd = portable_pty::CommandBuilder::new(_args[0].clone()); - let args = &mut VecDeque::from(_args.to_vec()); - VecDeque::pop_front(args); - for arg in args { - cmd.arg(arg); - } - cmd.cwd(std::env::current_dir()?); + pub fn write(&mut self, task: String) -> Result<()> { + if self.cancelled.load(std::sync::atomic::Ordering::SeqCst) { + return Err(format_err!("Can't write to a cancelled pty")); + } - for (key, val) in env.into_iter() { - cmd.env(key, val) + self.writer.write(task.as_bytes())?; + Ok(()) } - let child = pair.slave.spawn_command(cmd)?; - - // Read and parse output from the pty with reader - let mut reader = pair.master.try_clone_reader()?; - let mut writer = pair.master.take_writer()?; - - let pty_id = child.process_id().expect("Missing process id????"); - - let child_lock = Arc::new(Mutex::new(child)); - - let child_lock_reaper = child_lock.clone(); - tokio::task::spawn(async move { - if let Err(err) = tokio::task::spawn_blocking(move || { - std::io::copy(&mut reader, &mut PtyWriter { channel, pty_id }) - }) - .await - { - error!("Error occurred copying from pty to channels: {}", err); + pub async fn session_join( + &mut self, + session: i32, + sender: tokio::sync::mpsc::UnboundedSender, + ) -> Result<()> { + if self.cancelled.load(std::sync::atomic::Ordering::SeqCst) { + return Err(format_err!("Can't add a session to a cancelled pty")); }; + let mut cmd = goval::Command::default(); - let _read = crate::CHANNEL_MESSAGES.read().await; - if !_read.contains_key(&channel) { - return Err(AnyError::new(Error::new( - std::io::ErrorKind::NotFound, - "Owning channel", - ))); - } + cmd.body = Some(goval::command::Body::Output( + self.scrollback.read().await.clone(), + )); + cmd.session = session; + cmd.channel = self.channel; - let exit_code; + sender.send(IPCMessage { + command: cmd, + session, + })?; - if let Some(code) = child_lock_reaper.lock().await.try_wait()? { - exit_code = code.exit_code() as i32; - } else { - exit_code = 0; - } + self.sessions.write().await.insert(session, sender); - let queue = _read.get(&channel).unwrap().clone(); - drop(_read); - queue.push(ChannelMessage::ProcessDead(pty_id, exit_code)); Ok(()) - }); - - let queue = Arc::new(deadqueue::unlimited::Queue::new()); - - if let Some(session_map) = sessions { - PTY_SESSION_MAP.write().await.insert(pty_id, session_map); - } else { - PTY_SESSION_MAP.write().await.insert(pty_id, vec![]); } - let mut pty_channel_writer = crate::PROCCESS_CHANNEL_TO_ID.write().await; - if pty_channel_writer.contains_key(&channel) { - drop(pty_channel_writer); - return Err(AnyError::new(Error::new( - ErrorKind::AlreadyExists, - "Channel already has a PTY/CMD", - ))); - } else { - pty_channel_writer.insert(channel, pty_id); - } - - drop(pty_channel_writer); - - crate::PROCCESS_WRITE_MESSAGES - .write() - .await - .insert(pty_id, queue.clone()); - - let (task, handle) = abortable(async move { - loop { - let task = queue.pop().await; - if let Err(err) = writer.write(task.as_bytes()) { - return err; - } - } - }); - - PTY_CANCELLATION_MAP.write().await.insert(pty_id, handle); - - tokio::spawn(async move { - match task.await { - Ok(err) => { - error!("Error occurred while passing writes to pty: {}", err) - } - Err(_) => { - let mut child = child_lock.lock().await; - match child.kill() { - Ok(_) => {} - Err(err) => { - warn!("Failed to kill pty child: {}", err) - } - } - drop(child); - } + pub async fn session_leave(&mut self, session: i32) -> Result<()> { + if self.cancelled.load(std::sync::atomic::Ordering::SeqCst) { + return Err(format_err!("Can't remove a session from a cancelled pty")); } - }); - - Ok(pty_id) + self.sessions.write().await.remove(&session); + Ok(()) + } } - -// async fn op_pty_write_msg(id: u32, msg: String) -> Result<()> { -// match crate::PROCCESS_WRITE_MESSAGES.read().await.get(&id) { -// Some(queue) => { -// queue.push(msg); - -// Ok(()) -// } -// None => Err(format_err!("Couldn't find pty {} to write to", id)), -// } -// } - -// async fn op_destroy_pty(id: u32, channel_id: i32) -> Result<()> { -// if let Some(cancel) = PTY_CANCELLATION_MAP.read().await.get(&id) { -// cancel.abort(); -// } else { -// return Err(format_err!("Couldn't find pty {} to write to", id)); -// } - -// PTY_CANCELLATION_MAP.write().await.remove(&id); -// PTY_SESSION_MAP.write().await.remove(&id); -// crate::PROCCESS_WRITE_MESSAGES.write().await.remove(&id); -// crate::PROCCESS_CHANNEL_TO_ID -// .write() -// .await -// .remove(&channel_id); - -// Ok(()) -// } diff --git a/src/goval_server.rs b/src/goval_server.rs index cb09031..940d454 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -276,10 +276,15 @@ async fn open_channel( trace!(channel = channel_id_held; "Added channel to queue list"); tokio::spawn(async move { - let channel = - homeval_services::Channel::new(channel_id, service, _channel_name, writer) - .await - .expect("TODO: Deal with this"); + let channel = homeval_services::Channel::new( + channel_id, + service, + _channel_name, + crate::DOTREPLIT_CONFIG.clone(), + writer, + ) + .await + .expect("TODO: Deal with this"); channel.start(reader).await; }); found = true; diff --git a/src/main.rs b/src/main.rs index 4b8f98a..7767dd8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,13 +7,17 @@ use std::{collections::HashMap, io::Error, sync::Arc}; use log::{debug, info}; use tokio::sync::{mpsc, Mutex, RwLock}; -use homeval_services::{ChannelMessage, ClientInfo, IPCMessage, ReplspaceMessage, ServiceMetadata}; +use homeval_services::{ + config::dotreplit::DotReplit, + ChannelMessage, + ClientInfo, + IPCMessage, + ServiceMetadata, + // ReplspaceMessage, +}; mod parse_paseto; -mod config; -use config::dotreplit::DotReplit; - #[cfg(feature = "replspace")] mod replspace_server; @@ -26,8 +30,10 @@ static CPU_STATS: LazyLock> = pub static IMPLEMENTED_SERVICES: LazyLock> = LazyLock::new(|| vec![]); -pub static DOTREPLIT_CONFIG: LazyLock = LazyLock::new(|| { - toml::from_str(&std::fs::read_to_string(".replit").unwrap_or("".to_string())).unwrap() +pub static DOTREPLIT_CONFIG: LazyLock>> = LazyLock::new(|| { + Arc::new(RwLock::const_new( + toml::from_str(&std::fs::read_to_string(".replit").unwrap_or("".to_string())).unwrap(), + )) }); static MAX_SESSION: LazyLock> = LazyLock::new(|| Mutex::new(0)); @@ -57,12 +63,12 @@ static PROCCESS_CHANNEL_TO_ID: LazyLock>> = static LAST_SESSION_USING_CHANNEL: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); -static REPLSPACE_CALLBACKS: LazyLock< - RwLock>>>, -> = LazyLock::new(|| RwLock::new(HashMap::new())); +// static REPLSPACE_CALLBACKS: LazyLock< +// RwLock>>>, +// > = LazyLock::new(|| RwLock::new(HashMap::new())); -static CHILD_PROCS_ENV_BASE: LazyLock>> = - LazyLock::new(|| RwLock::new(HashMap::new())); +// static CHILD_PROCS_ENV_BASE: LazyLock>> = +// LazyLock::new(|| RwLock::new(HashMap::new())); #[cfg(feature = "database")] mod database; From 274fe4aa605e2863eed5cf2b058be4cd964ae4b5 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sun, 8 Oct 2023 17:56:50 -0700 Subject: [PATCH 017/103] refactor: Remove unused js related code --- src/deno_extension/cmd.rs | 357 ---------------------------- src/deno_extension/database_faux.rs | 53 ----- src/deno_extension/database_real.rs | 63 ----- src/deno_extension/diff.rs | 74 ------ src/deno_extension/fs.rs | 182 -------------- src/deno_extension/fs_events.rs | 209 ---------------- src/deno_extension/messaging.rs | 107 --------- src/deno_extension/mod.rs | 44 ---- src/deno_extension/pty.rs | 292 ----------------------- src/deno_extension/quick_cmd.rs | 96 -------- src/deno_extension/random.rs | 99 -------- src/deno_extension/server_info.rs | 69 ------ src/deno_extension/sysinfo.rs | 81 ------- types/homeval-types/package.json | 10 - types/homeval-types/types.d.ts | 218 ----------------- 15 files changed, 1954 deletions(-) delete mode 100644 src/deno_extension/cmd.rs delete mode 100644 src/deno_extension/database_faux.rs delete mode 100644 src/deno_extension/database_real.rs delete mode 100644 src/deno_extension/diff.rs delete mode 100644 src/deno_extension/fs.rs delete mode 100644 src/deno_extension/fs_events.rs delete mode 100644 src/deno_extension/messaging.rs delete mode 100644 src/deno_extension/mod.rs delete mode 100644 src/deno_extension/pty.rs delete mode 100644 src/deno_extension/quick_cmd.rs delete mode 100644 src/deno_extension/random.rs delete mode 100644 src/deno_extension/server_info.rs delete mode 100644 src/deno_extension/sysinfo.rs delete mode 100644 types/homeval-types/package.json delete mode 100644 types/homeval-types/types.d.ts diff --git a/src/deno_extension/cmd.rs b/src/deno_extension/cmd.rs deleted file mode 100644 index f36301c..0000000 --- a/src/deno_extension/cmd.rs +++ /dev/null @@ -1,357 +0,0 @@ -use futures_util::{future::abortable, stream::AbortHandle, Future}; -use log::{as_error, error}; -use std::{ - collections::{HashMap, VecDeque}, - io::{Error, ErrorKind}, - pin::Pin, - process::Stdio, - sync::{Arc, LazyLock}, - task::{Context, Poll}, -}; - -use crate::channels::IPCMessage; - -use tokio::{ - io::{AsyncWrite, AsyncWriteExt}, - process::Command, - sync::{Mutex, RwLock}, -}; - -use deno_core::{error::AnyError, op, OpDecl}; - -use crate::JsMessage; - -static CMD_CANCELLATION_MAP: LazyLock>> = - LazyLock::new(|| RwLock::new(HashMap::new())); -static CMD_SESSION_MAP: LazyLock>>> = - LazyLock::new(|| RwLock::new(HashMap::new())); - -struct CmdWriter { - channel: i32, - cmd_id: u32, -} -async fn remove_refs(id: u32, channel_id: i32) { - CMD_CANCELLATION_MAP.write().await.remove(&id); - CMD_SESSION_MAP.write().await.remove(&id); - crate::PROCCESS_WRITE_MESSAGES.write().await.remove(&id); - crate::PROCCESS_CHANNEL_TO_ID - .write() - .await - .remove(&channel_id); -} - -async fn write_to_cmd(buf: &[u8], channel: i32, cmd_id: u32) -> Result { - let mut cmd = crate::goval::Command::default(); - let output: String; - match String::from_utf8(buf.to_vec()) { - Ok(str) => output = str, - Err(err) => { - error!("Invalid utf-8 output in pty handler"); - - return Err(Error::new(ErrorKind::Other, err.utf8_error())); - } - } - - cmd.body = Some(crate::goval::command::Body::Output(output)); - - cmd.channel = channel; - - let sessions; - let _key = CMD_SESSION_MAP.read().await; - if let Some(session_map) = _key.get(&cmd_id) { - sessions = session_map; - } else { - return Err(std::io::Error::new( - ErrorKind::ConnectionAborted, - "Cmd is gone", - )); - } - - for session in sessions.iter() { - if let Some(sender) = crate::SESSION_MAP.read().await.get(&session) { - let mut to_send = cmd.clone(); - to_send.session = *session; - - match sender.send(IPCMessage::from_cmd(to_send, *session)) { - Ok(_) => {} - Err(err) => { - return Err(Error::new(ErrorKind::Other, err)); - } - } - } else { - return Err(Error::new( - ErrorKind::NotFound, - "Missing session in cmd writer", - )); - } - } - - Ok(buf.len()) -} - -impl AsyncWrite for CmdWriter { - fn poll_write( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - let mut future: Pin>>> = - Box::pin(write_to_cmd(buf, self.channel, self.cmd_id)); - future.as_mut().poll(cx) - } - - fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) - } - - fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { - Poll::Ready(Ok(())) - } -} - -#[op] -async fn op_register_cmd( - _args: Vec, - channel: i32, - sessions: Option>, - _env: Option>, -) -> Result { - let mut env = crate::CHILD_PROCS_ENV_BASE.read().await.clone(); - - if let Some(env_vars) = _env { - env.extend(env_vars); - } - - let args = &mut VecDeque::from(_args.to_vec()); - let mut cmd = Command::new(VecDeque::pop_front(args).expect("Missing command")); - for arg in args { - cmd.arg(arg); - } - cmd.current_dir(std::env::current_dir()?); - - cmd.envs(env); - - cmd.stdout(Stdio::piped()); - cmd.stderr(Stdio::piped()); - cmd.stdin(Stdio::piped()); - - let mut child = cmd.spawn()?; - - // let output_channel = oneshot::channel::(); - - // tokio::spawn(async {}); - - // Read and parse output from the cmd with reader - let stdout_opt = child.stdout.take(); - let stderr_opt = child.stderr.take(); - let stdin_opt = child.stdin.take(); - - let cmd_id = child.id().expect("Missing process id????"); - - let queue = Arc::new(deadqueue::unlimited::Queue::new()); - - if let Some(session_map) = sessions { - CMD_SESSION_MAP.write().await.insert(cmd_id, session_map); - } else { - CMD_SESSION_MAP.write().await.insert(cmd_id, vec![]); - } - - let mut cmd_channel_writer = crate::PROCCESS_CHANNEL_TO_ID.write().await; - if cmd_channel_writer.contains_key(&channel) { - drop(cmd_channel_writer); - return Err(AnyError::new(Error::new( - ErrorKind::AlreadyExists, - "Channel already has a PTY/CMDs", - ))); - } else { - cmd_channel_writer.insert(channel, cmd_id); - } - - drop(cmd_channel_writer); - - crate::PROCCESS_WRITE_MESSAGES - .write() - .await - .insert(cmd_id, queue.clone()); - - let child_lock = Arc::new(Mutex::new(child)); - - let (task, handle) = abortable(tokio::spawn(async move { - tokio::select! { - res = async move { - if let Some(mut stdin) = stdin_opt { - loop { - let task = queue.pop().await; - if let Err(err) = stdin.write(task.as_bytes()).await { - return err; - } - } - } else { - Error::new(ErrorKind::BrokenPipe, "stdin missing") - } - } => { - error!(error = as_error!(res); "Error occurred while passing writes to cmd"); - }, - _ = async move { - let stderr_cpy; - let stdout_cpy; - - if let Some(mut stdout) = stdout_opt { - let mut pty_writer_out = CmdWriter { channel, cmd_id }; - stdout_cpy = Some(async move { - tokio::io::copy(&mut stdout, &mut pty_writer_out).await - }); - } else { - stdout_cpy = None; - } - - if let Some(mut stderr) = stderr_opt { - let mut pty_writer_err = CmdWriter { channel, cmd_id }; - stderr_cpy = Some(async move { - tokio::io::copy(&mut stderr, &mut pty_writer_err).await - }) - } else { - stderr_cpy = None; - } - - let final_res; - - if stderr_cpy.is_some() && stdout_cpy.is_some() { - tokio::select! { - res = stderr_cpy.unwrap() => { - final_res = res - } - res = stdout_cpy.unwrap() => { - final_res = res - } - } - } else if let Some(task) = stderr_cpy { - final_res = task.await; - } else if let Some(task) = stdout_cpy { - final_res = task.await; - } - // else if child_lock.lock().await.out { - - // } - else { - final_res = Err(Error::new(ErrorKind::NotFound, "Both stdout and stderr missing")) - } - - if let Err(err) = final_res { - error!(error = as_error!(err); "Error occurred copying from cmd to channels"); - }; - } => {}, - } - })); - - CMD_CANCELLATION_MAP.write().await.insert(cmd_id, handle); - - // tokio::spawn(); - tokio::spawn(async move { - let res = task.await; - - remove_refs(cmd_id, channel).await; - - let _read = crate::CHANNEL_MESSAGES.read().await; - if !_read.contains_key(&channel) { - return Err(AnyError::new(Error::new( - std::io::ErrorKind::NotFound, - "Cmd missing owning channel", - ))); - } - - let mut child = child_lock.lock().await; - - let exit_code; - - if let Some(code) = child.try_wait()? { - exit_code = code.code().unwrap_or(1); - } else { - exit_code = 0; - } - - let queue = _read.get(&channel).unwrap().clone(); - drop(_read); - queue.push(JsMessage::ProcessDead(cmd_id, exit_code)); - - match res { - Ok(res) => { - if let Err(err) = res { - error!(error = as_error!(err); "Join Error encountered"); - } - } - Err(_) => { - child.kill().await.expect("Failed to kill cmd child"); - } - } - - Ok(()) - }); - - Ok(cmd_id) -} - -#[op] -async fn op_cmd_add_session(id: u32, session: i32) -> Result<(), AnyError> { - CMD_SESSION_MAP - .write() - .await - .entry(id) - .and_modify(|sessions| sessions.push(session)); - Ok(()) -} - -#[op] -async fn op_cmd_remove_session(id: u32, session: i32) -> Result<(), AnyError> { - CMD_SESSION_MAP - .write() - .await - .entry(id) - .and_modify(|sessions| { - if let Some(pos) = sessions.iter().position(|x| *x == session) { - sessions.swap_remove(pos); - } - }); - Ok(()) -} - -#[op] -async fn op_cmd_write_msg(id: u32, msg: String) -> Result<(), AnyError> { - match crate::PROCCESS_WRITE_MESSAGES.read().await.get(&id) { - Some(queue) => { - queue.push(msg); - - Ok(()) - } - None => Err(AnyError::new(Error::new( - ErrorKind::NotFound, - format!("Couldn't find cmd {} to write to", id), - ))), - } -} - -#[op] -async fn op_destroy_cmd(id: u32, channel_id: i32) -> Result<(), AnyError> { - if let Some(cancel) = CMD_CANCELLATION_MAP.read().await.get(&id) { - cancel.abort(); - } else { - return Err(AnyError::new(Error::new( - ErrorKind::NotFound, - format!("Couldn't find cmd {} to destroy", id), - ))); - } - - remove_refs(id, channel_id).await; - - Ok(()) -} - -pub fn get_op_decls() -> Vec { - vec![ - op_destroy_cmd::decl(), - op_register_cmd::decl(), - op_cmd_write_msg::decl(), - op_cmd_add_session::decl(), - op_cmd_remove_session::decl(), - ] -} diff --git a/src/deno_extension/database_faux.rs b/src/deno_extension/database_faux.rs deleted file mode 100644 index d177d74..0000000 --- a/src/deno_extension/database_faux.rs +++ /dev/null @@ -1,53 +0,0 @@ -use std::collections::HashMap; - -use deno_core::{error::AnyError, op, OpDecl}; -use serde::{Deserialize, Serialize}; -use tokio::sync::{OnceCell, RwLock}; - -#[derive(Clone, Serialize, Deserialize)] -pub struct File { - pub name: String, - pub crc32: i32, - pub contents: String, - pub history: Vec, -} - -static FILES: OnceCell>> = OnceCell::const_new(); - -#[op] -fn op_database_exists() -> Result { - Ok(true) -} - -#[op] -async fn op_database_get_file(file_name: String) -> Result, AnyError> { - match FILES - .get_or_init(|| async { RwLock::new(HashMap::new()) }) - .await - .read() - .await - .get(&file_name) - { - Some(file) => Ok(Some(file.clone())), - None => Ok(None), - } -} - -#[op] -async fn op_database_set_file(file: File) -> Result<(), AnyError> { - FILES - .get_or_init(|| async { RwLock::new(HashMap::new()) }) - .await - .write() - .await - .insert(file.name.clone(), file); - Ok(()) -} - -pub fn get_op_decls() -> Vec { - vec![ - op_database_exists::decl(), - op_database_get_file::decl(), - op_database_set_file::decl(), - ] -} diff --git a/src/deno_extension/database_real.rs b/src/deno_extension/database_real.rs deleted file mode 100644 index a4eaec9..0000000 --- a/src/deno_extension/database_real.rs +++ /dev/null @@ -1,63 +0,0 @@ -use std::io::Error; - -use deno_core::{error::AnyError, op, OpDecl}; -use entity::files; -use log::{as_debug, trace}; -use sea_orm::entity::EntityTrait; -use sea_query::OnConflict; - -#[op] -fn op_database_exists() -> Result { - match crate::DATABASE.get() { - Some(_) => Ok(true), - None => Ok(false), - } -} - -#[op] -async fn op_database_get_file(file_name: String) -> Result, AnyError> { - match crate::DATABASE.get() { - Some(db) => Ok(files::Entity::find_by_id(file_name).one(db).await?), - None => Err(Error::new( - std::io::ErrorKind::NotConnected, - "No database connection found", - ) - .into()), - } -} - -#[op] -async fn op_database_set_file(model: files::Model) -> Result<(), AnyError> { - match crate::DATABASE.get() { - Some(db) => { - trace!(file = as_debug!(model); "Inserting file to db"); - let active: files::ActiveModel = model.into(); - files::Entity::insert(active) - .on_conflict( - OnConflict::column(files::Column::Name) - .update_columns([ - files::Column::Contents, - files::Column::Crc32, - files::Column::History, - ]) - .to_owned(), - ) - .exec(db) - .await?; - Ok(()) - } - None => Err(Error::new( - std::io::ErrorKind::NotConnected, - "No database connection found", - ) - .into()), - } -} - -pub fn get_op_decls() -> Vec { - vec![ - op_database_exists::decl(), - op_database_get_file::decl(), - op_database_set_file::decl(), - ] -} diff --git a/src/deno_extension/diff.rs b/src/deno_extension/diff.rs deleted file mode 100644 index 918529f..0000000 --- a/src/deno_extension/diff.rs +++ /dev/null @@ -1,74 +0,0 @@ -use core::time::Duration; -use deno_core::{error::AnyError, op, OpDecl}; -use serde::Serialize; -use similar::TextDiff; - -#[derive(Serialize, Clone)] -#[serde(rename_all = "camelCase")] -enum DiffPart { - Delete(u32), - Skip(u32), - Insert(String), -} - -#[op] -async fn op_diff_texts(old: String, new: String) -> Result, AnyError> { - let parts = tokio::task::spawn_blocking(move || { - let mut _differ = TextDiff::configure(); - let differ = _differ.timeout(Duration::from_secs(1)); - let diff = differ.diff_chars(&old, &new); - - let mut parts = vec![]; - let mut last_op: Option = None; - for part in diff.iter_all_changes() { - let mut new_op: Option = None; - match part.tag() { - similar::ChangeTag::Equal => { - if let Some(DiffPart::Skip(amount)) = last_op.clone() { - last_op = Some(DiffPart::Skip(amount + part.value().len() as u32)) - } else { - new_op = Some(DiffPart::Skip(part.value().len() as u32)); - } - } - similar::ChangeTag::Delete => { - if let Some(DiffPart::Delete(amount)) = last_op.clone() { - last_op = Some(DiffPart::Delete(amount + part.value().len() as u32)) - } else { - new_op = Some(DiffPart::Delete(part.value().len() as u32)); - } - } - similar::ChangeTag::Insert => { - if let Some(DiffPart::Insert(same)) = last_op.clone() { - last_op = Some(DiffPart::Insert(same + part.value())) - } else { - new_op = Some(DiffPart::Insert(part.value().to_string())); - } - } - } - - if let Some(new_part) = new_op { - if let Some(last_part) = last_op.clone() { - parts.push(last_part); - } - - last_op = Some(new_part); - } - } - - if let Some(op) = last_op { - match op { - DiffPart::Skip(_) => {} - _ => parts.push(op), - } - } - - parts - }) - .await?; - - Ok(parts) -} - -pub fn get_op_decls() -> Vec { - vec![op_diff_texts::decl()] -} diff --git a/src/deno_extension/fs.rs b/src/deno_extension/fs.rs deleted file mode 100644 index 73129df..0000000 --- a/src/deno_extension/fs.rs +++ /dev/null @@ -1,182 +0,0 @@ -use std::{io::Error, time::SystemTime}; - -use deno_core::{error::AnyError, op, OpDecl}; -use log::error; -use serde::Serialize; -use tokio::{fs, io::AsyncWriteExt}; -use tokio_stream::{wrappers::ReadDirStream, StreamExt}; - -#[derive(Serialize, Debug)] -#[serde(rename_all = "camelCase")] -pub struct File { - pub path: String, - pub r#type: FileType, -} - -#[derive(Serialize, Debug)] -#[serde(rename_all = "camelCase")] -pub enum FileType { - File, - Directory, - Symlink, -} - -impl FileType { - pub fn from_file_type(file_type: std::fs::FileType) -> Result { - let ret: FileType; - - if file_type.is_dir() { - ret = FileType::Directory - } else if file_type.is_file() { - ret = FileType::File - } else if file_type.is_symlink() { - ret = FileType::Symlink - } else { - return Err(AnyError::new(Error::new( - std::io::ErrorKind::InvalidData, - "invalid file type", - ))); - } - - Ok(ret) - } -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -pub struct FileStat { - pub exists: bool, - #[serde(rename = "type")] - pub file_type: FileType, - pub size: u64, - pub file_mode: String, - pub mod_time: u64, -} - -async fn inner_stat(path: String) -> Result, AnyError> { - match fs::metadata(path).await { - Err(_) => Ok(None), - Ok(stat_info) => Ok(Some(FileStat { - exists: true, - file_type: FileType::from_file_type(stat_info.file_type())?, - size: stat_info.len(), - file_mode: "".to_string(), - mod_time: stat_info - .modified()? - .duration_since(SystemTime::UNIX_EPOCH)? - .as_secs(), - })), - } -} - -// TODO: function to stat multiple files at once - -#[op] -async fn op_stat_file(path: String) -> Result { - match inner_stat(path.clone()).await? { - None => Err(Error::new( - std::io::ErrorKind::NotFound, - format!("File not found: {}", path), - ) - .into()), - Some(stat) => Ok(stat), - } -} - -#[op] -async fn op_list_dir(path: String) -> Result, AnyError> { - let mut dir = ReadDirStream::new(fs::read_dir(path.clone()).await?); - let mut ret = Vec::::new(); - let parent = std::path::Path::new(&path); - while let Some(fs_path) = dir.next().await { - let file = fs_path?; - if let Some(str_path) = file.path().strip_prefix(parent)?.to_str() { - let file_type = FileType::from_file_type(file.file_type().await?)?; - - ret.push(File { - path: str_path.to_string(), - r#type: file_type, - }); - } else { - error!("Got none from Path#to_str in op_list_dir") - } - } - - Ok(ret) -} - -#[op] -async fn op_make_dir(path: String) -> Result<(), AnyError> { - fs::create_dir_all(path).await?; - Ok(()) -} - -#[op] -async fn op_write_file(path: String, contents: Vec) -> Result<(), AnyError> { - let mut file = fs::OpenOptions::new() - .write(true) - .create(true) - .open(path) - .await?; - file.set_len(0).await?; - file.write(&contents).await?; - Ok(()) -} - -#[op] -async fn op_read_file(path: String) -> Result, AnyError> { - Ok(fs::read(path).await?) -} - -#[op] -async fn op_remove_file(path: String) -> Result<(), AnyError> { - let stat = fs::metadata(path.clone()).await?; - if stat.is_dir() { - Ok(fs::remove_dir_all(path).await?) - } else { - Ok(fs::remove_file(path).await?) - } -} - -#[op] -async fn op_move_file(old_path: String, new_path: String) -> Result<(), AnyError> { - Ok(fs::rename(old_path, new_path).await?) -} - -#[op] -async fn op_read_file_string(path: String) -> Result { - Ok(String::from_utf8(fs::read(path).await?)?) -} - -#[op] -async fn op_write_file_string(path: String, contents: String) -> Result<(), AnyError> { - let mut file = fs::OpenOptions::new() - .write(true) - .create(true) - .open(path) - .await?; - file.set_len(0).await?; - file.write(&contents.as_bytes()).await?; - Ok(()) -} - -#[op] -fn op_get_working_dir() -> Result { - // TODO: deal with possible panic from unwrap - Ok(std::env::current_dir()?.to_str().unwrap().to_string()) -} - -pub fn get_op_decls() -> Vec { - vec![ - op_stat_file::decl(), - op_list_dir::decl(), - op_make_dir::decl(), - op_write_file::decl(), - op_read_file::decl(), - op_remove_file::decl(), - op_move_file::decl(), - op_read_file_string::decl(), - op_write_file_string::decl(), - op_get_working_dir::decl(), - ] -} diff --git a/src/deno_extension/fs_events.rs b/src/deno_extension/fs_events.rs deleted file mode 100644 index a244fe2..0000000 --- a/src/deno_extension/fs_events.rs +++ /dev/null @@ -1,209 +0,0 @@ -use deno_core::{op, OpDecl}; -use log::{as_debug, debug, error, trace}; -use notify_debouncer_full::{ - new_debouncer, - notify::{self, event::ModifyKind, Event, EventKind, RecommendedWatcher, Watcher}, - DebounceEventResult, Debouncer, FileIdMap, -}; -use serde::Serialize; - -use deno_core::error::AnyError; - -use std::{ - collections::HashMap, - io::Error, - path::Path, - sync::{Arc, LazyLock}, - time::Duration, -}; -use tokio::sync::{Mutex, RwLock}; - -static FILE_WATCHER_MAP: LazyLock< - RwLock>>>>, -> = LazyLock::new(|| RwLock::new(HashMap::new())); -static FILE_WATCHER_MESSAGES: LazyLock< - RwLock>>>, -> = LazyLock::new(|| RwLock::new(HashMap::new())); -static MAX_WATCHER: LazyLock> = LazyLock::new(|| Mutex::new(0)); - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -pub enum FinalEvent { - Remove(String), - Create(String), - Modify(String), - Rename(String, String), - Err(String), - Shutdown(bool), -} - -fn notify_event_to_final(event: &Event) -> Result, AnyError> { - let base = std::env::current_dir()?; - let file_name = event.paths[0] - .strip_prefix(base.clone())? - .to_str() - .unwrap() - .to_string(); - match event.kind { - EventKind::Create(_) => Ok(Some(FinalEvent::Create(file_name))), - EventKind::Modify(_kind @ ModifyKind::Name(notify::event::RenameMode::Both)) => { - Ok(Some(FinalEvent::Rename( - file_name, - event.paths[1] - .strip_prefix(base)? - .to_str() - .unwrap() - .to_string(), - ))) - } - EventKind::Modify(_kind @ ModifyKind::Name(notify::event::RenameMode::From)) => { - Ok(Some(FinalEvent::Remove(file_name.to_string()))) - } - EventKind::Modify(_kind @ ModifyKind::Name(notify::event::RenameMode::To)) => { - Ok(Some(FinalEvent::Create(file_name.to_string()))) - } - EventKind::Modify(_) => Ok(Some(FinalEvent::Modify(file_name))), - EventKind::Remove(_) => Ok(Some(FinalEvent::Remove(file_name))), - _ => Ok(None), - } -} - -#[op] -async fn op_shutdown_filewatcher(watcher: u32) -> Result<(), AnyError> { - let mut _read = FILE_WATCHER_MAP.write().await; - if !_read.contains_key(&watcher) { - return Err(AnyError::new(Error::new( - std::io::ErrorKind::NotFound, - "Watcher not found", - ))); - } - - let debouncer_lock = _read.get(&watcher).unwrap().clone(); - _read.remove(&watcher); - drop(_read); - - match Arc::try_unwrap(debouncer_lock) { - Ok(inner) => { - inner.into_inner().stop_nonblocking(); - } - Err(_) => { - debug!(watcher = watcher; "Could not steal Debouncer from Arc"); - } - } - - let mut _read = FILE_WATCHER_MESSAGES.write().await; - if !_read.contains_key(&watcher) { - return Err(AnyError::new(Error::new( - std::io::ErrorKind::NotFound, - "Watcher not found", - ))); - } - - let queue = _read.get(&watcher).unwrap().clone(); - queue.push(FinalEvent::Shutdown(true)); - _read.remove(&watcher); - drop(_read); - - trace!(watcher = watcher; "Shutdown watcher"); - - Ok(()) -} - -#[op] -async fn op_make_filewatcher() -> Result { - let mut max_watcher = MAX_WATCHER.lock().await; - *max_watcher += 1; - let watcher_id = max_watcher.clone(); - drop(max_watcher); - - let queue: Arc> = - Arc::new(deadqueue::unlimited::Queue::new()); - - FILE_WATCHER_MESSAGES - .write() - .await - .insert(watcher_id, queue.clone()); - - let queue_writer = queue.clone(); - // tokio::spawn(async move { - let queue_debounced = queue_writer.clone(); - tokio::task::spawn_blocking(move || { - let debouncer: Debouncer = - new_debouncer( - Duration::from_secs(1), - None, - move |result: DebounceEventResult| match result { - Ok(events) => events.iter().for_each(|event| { - if let Some(final_event) = notify_event_to_final(event).unwrap() { - queue_debounced.push(final_event); - } - }), - Err(errors) => errors.iter().for_each(|error| { - error!(error = as_debug!(error); "Error in debouncer"); - queue_debounced.push(FinalEvent::Err(error.to_string())) - }), - }, - ) - .unwrap(); - - let mut watcher_map = FILE_WATCHER_MAP.blocking_write(); - watcher_map.insert(watcher_id, Arc::new(Mutex::new(debouncer))); - }) - .await?; - // }); - Ok(watcher_id) -} - -#[op] -async fn op_recv_fsevent(watcher: u32) -> Result { - let _read = FILE_WATCHER_MESSAGES.read().await; - if !_read.contains_key(&watcher) { - return Err(AnyError::new(Error::new( - std::io::ErrorKind::NotFound, - "Watcher not found", - ))); - } - - let queue = _read.get(&watcher).unwrap().clone(); - drop(_read); - - let res = queue.pop().await; - Ok(res) -} - -#[op] -async fn op_watch_files(watcher: u32, files: Vec) -> Result<(), AnyError> { - let _read = FILE_WATCHER_MAP.read().await; - if !_read.contains_key(&watcher) { - return Err(AnyError::new(Error::new( - std::io::ErrorKind::NotFound, - "Watcher not found", - ))); - } - - let debouncer_lock = _read.get(&watcher).unwrap().clone(); - drop(_read); - - let mut debouncer = debouncer_lock.lock().await; - - for file in files { - let path = Path::new(&file); - debouncer - .watcher() - .watch(path, notify::RecursiveMode::NonRecursive)?; - debouncer - .cache() - .add_root(path, notify::RecursiveMode::NonRecursive) - } - - Ok(()) -} - -pub fn get_op_decls() -> Vec { - vec![ - op_shutdown_filewatcher::decl(), - op_make_filewatcher::decl(), - op_recv_fsevent::decl(), - op_watch_files::decl(), - ] -} diff --git a/src/deno_extension/messaging.rs b/src/deno_extension/messaging.rs deleted file mode 100644 index 73b20ec..0000000 --- a/src/deno_extension/messaging.rs +++ /dev/null @@ -1,107 +0,0 @@ -use deno_core::{error::AnyError, op, OpDecl}; -use log::{as_debug, error, trace}; -use serde::{Deserialize, Serialize}; -use std::io::Error; - -use crate::{channels::IPCMessage, parse_paseto::ClientInfo}; - -#[op] -async fn op_send_msg(msg: IPCMessage) -> Result<(), AnyError> { - if let Some(sender) = crate::SESSION_MAP.read().await.get(&msg.session.clone()) { - sender.send(msg)?; - } else { - error!("Missing session outbound message queue in op_send_msg") - } - Ok(()) -} - -#[derive(Serialize, Deserialize, Clone)] -#[serde(rename_all = "camelCase")] -pub enum JsMessage { - #[serde(rename = "ipc")] - IPC(IPCMessage), - Attach(i32), - Detach(i32), - Close(i32), - ProcessDead(u32, i32), - CmdDead(i32), - Replspace(i32, ReplspaceMessage), // session, message - Shutdown(bool), // Shutdown the service, value has to be true so that runtime.js can match it in an if check -} - -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "camelCase")] -pub enum ReplspaceMessage { - GithubTokenReq(String), // nonce - OpenFileReq(String, bool, String), // file, wait for close, nonce - OpenMultipleFiles(Vec, String), // files, nonce - - GithubTokenRes(String), // token - OpenFileRes, -} - -#[op] -async fn op_ack_shutdown(channel: i32) -> Result<(), AnyError> { - trace!(channel = channel; "Channel ack'ed shutdown"); - crate::CHANNEL_MESSAGES.write().await.remove(&channel); - Ok(()) -} - -#[op] -async fn op_recv_info(channel: i32) -> Result { - let _read = crate::CHANNEL_MESSAGES.read().await; - if !_read.contains_key(&channel) { - return Err(AnyError::new(Error::new( - std::io::ErrorKind::NotFound, - "not found", - ))); - } - let queue = _read.get(&channel).unwrap().clone(); - drop(_read); - - let res = queue.pop().await; - Ok(res) -} - -#[op] -async fn op_replspace_reply(nonce: String, reply: ReplspaceMessage) -> Result<(), AnyError> { - crate::REPLSPACE_CALLBACKS - .write() - .await - .entry(nonce.clone()) - .and_modify(|entry| { - let sender = entry.take().unwrap(); - // let sender = Arc::try_unwrap(_sender.clone()).unwrap(); - match sender.send(reply) { - Ok(_) => {} - Err(val) => error!( - message = as_debug!(val); - "Failed to send replspace api reply" - ), - }; - }); - Ok(()) -} - -#[op] -async fn op_user_info(session: i32) -> Result { - let _read = crate::SESSION_CLIENT_INFO.read().await; - if !_read.contains_key(&session) { - return Ok(ClientInfo::default()); - } - - match _read.get(&session) { - Some(info) => Ok(info.clone()), - None => Ok(ClientInfo::default()), - } -} - -pub fn get_op_decls() -> Vec { - vec![ - op_ack_shutdown::decl(), - op_recv_info::decl(), - op_send_msg::decl(), - op_user_info::decl(), - op_replspace_reply::decl(), - ] -} diff --git a/src/deno_extension/mod.rs b/src/deno_extension/mod.rs deleted file mode 100644 index dd3be11..0000000 --- a/src/deno_extension/mod.rs +++ /dev/null @@ -1,44 +0,0 @@ -use deno_core::{Extension, OpDecl}; - -pub mod cmd; -pub mod diff; -pub mod fs; -pub mod fs_events; -pub mod messaging; -pub mod pty; -pub mod quick_cmd; -pub mod random; -pub mod server_info; -pub mod sysinfo; - -#[cfg(feature = "database")] -pub mod database_real; -#[cfg(feature = "database")] -use database_real as database; - -#[cfg(not(feature = "database"))] -pub mod database_faux; -#[cfg(not(feature = "database"))] -use database_faux as database; - -pub use messaging::JsMessage; -pub use random::Service; - -pub fn make_extension() -> Extension { - let mut ops: Vec = vec![]; - - // Add extension op decls - ops.append(&mut cmd::get_op_decls()); - ops.append(&mut diff::get_op_decls()); - ops.append(&mut fs::get_op_decls()); - ops.append(&mut fs_events::get_op_decls()); - ops.append(&mut messaging::get_op_decls()); - ops.append(&mut pty::get_op_decls()); - ops.append(&mut quick_cmd::get_op_decls()); - ops.append(&mut random::get_op_decls()); - ops.append(&mut server_info::get_op_decls()); - ops.append(&mut sysinfo::get_op_decls()); - ops.append(&mut database::get_op_decls()); - - Extension::builder("homeval").ops(ops).build() -} diff --git a/src/deno_extension/pty.rs b/src/deno_extension/pty.rs deleted file mode 100644 index 33b107f..0000000 --- a/src/deno_extension/pty.rs +++ /dev/null @@ -1,292 +0,0 @@ -use futures_util::{future::abortable, stream::AbortHandle}; -use log::{error, warn}; -use portable_pty::PtySize; -use std::{ - collections::{HashMap, VecDeque}, - io::{Error, ErrorKind, Write}, - sync::{Arc, LazyLock}, -}; - -use crate::channels::IPCMessage; - -use tokio::sync::{Mutex, RwLock}; - -use deno_core::{error::AnyError, op, OpDecl}; - -use crate::JsMessage; - -static PTY_CANCELLATION_MAP: LazyLock>> = - LazyLock::new(|| RwLock::new(HashMap::new())); -static PTY_SESSION_MAP: LazyLock>>> = - LazyLock::new(|| RwLock::new(HashMap::new())); - -struct PtyWriter { - channel: i32, - pty_id: u32, -} - -impl Write for PtyWriter { - fn write(&mut self, buf: &[u8]) -> std::io::Result { - let mut cmd = crate::goval::Command::default(); - let output: String; - match String::from_utf8(buf.to_vec()) { - Ok(str) => output = str, - Err(err) => { - error!("Invalid utf-8 output in pty handler"); - - return Err(Error::new(ErrorKind::Other, err.utf8_error())); - } - } - - cmd.body = Some(crate::goval::command::Body::Output(output)); - cmd.channel = self.channel; - - let sessions; - let _key = PTY_SESSION_MAP.blocking_read(); - if let Some(session_map) = _key.get(&self.pty_id) { - sessions = session_map; - } else { - return Err(std::io::Error::new( - ErrorKind::ConnectionAborted, - "Pty is gone", - )); - } - - for session in sessions.iter() { - if let Some(sender) = crate::SESSION_MAP.blocking_read().get(session) { - let mut to_send = cmd.clone(); - to_send.session = *session; - - match sender.send(IPCMessage::from_cmd(to_send, *session)) { - Ok(_) => {} - Err(err) => { - return Err(Error::new(ErrorKind::Other, err)); - } - } - } else { - return Err(Error::new( - ErrorKind::NotFound, - "Missing session in pty writer", - )); - } - } - - Ok(buf.len()) - } - - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) - } -} - -#[op] -async fn op_register_pty( - _args: Vec, - channel: i32, - sessions: Option>, - _env: Option>, -) -> Result { - let mut env = crate::CHILD_PROCS_ENV_BASE.read().await.clone(); - - if let Some(env_vars) = _env { - env.extend(env_vars); - } - - let pty_system = portable_pty::native_pty_system(); - - // Create a new pty - let pair = pty_system.openpty(PtySize { - rows: 24, - cols: 80, - // Not all systems support pixel_width, pixel_height, - // but it is good practice to set it to something - // that matches the size of the selected font. That - // is more complex than can be shown here in this - // brief example though! - pixel_width: 0, - pixel_height: 0, - })?; - - // Spawn a shell into the pty - let mut cmd = portable_pty::CommandBuilder::new(_args[0].clone()); - let args = &mut VecDeque::from(_args.to_vec()); - VecDeque::pop_front(args); - for arg in args { - cmd.arg(arg); - } - cmd.cwd(std::env::current_dir()?); - - for (key, val) in env.into_iter() { - cmd.env(key, val) - } - - let child = pair.slave.spawn_command(cmd)?; - - // Read and parse output from the pty with reader - let mut reader = pair.master.try_clone_reader()?; - let mut writer = pair.master.take_writer()?; - - let pty_id = child.process_id().expect("Missing process id????"); - - let child_lock = Arc::new(Mutex::new(child)); - - let child_lock_reaper = child_lock.clone(); - tokio::task::spawn(async move { - if let Err(err) = tokio::task::spawn_blocking(move || { - std::io::copy(&mut reader, &mut PtyWriter { channel, pty_id }) - }) - .await - { - error!("Error occurred copying from pty to channels: {}", err); - }; - - let _read = crate::CHANNEL_MESSAGES.read().await; - if !_read.contains_key(&channel) { - return Err(AnyError::new(Error::new( - std::io::ErrorKind::NotFound, - "Owning channel", - ))); - } - - let exit_code; - - if let Some(code) = child_lock_reaper.lock().await.try_wait()? { - exit_code = code.exit_code() as i32; - } else { - exit_code = 0; - } - - let queue = _read.get(&channel).unwrap().clone(); - drop(_read); - queue.push(JsMessage::ProcessDead(pty_id, exit_code)); - Ok(()) - }); - - let queue = Arc::new(deadqueue::unlimited::Queue::new()); - - if let Some(session_map) = sessions { - PTY_SESSION_MAP.write().await.insert(pty_id, session_map); - } else { - PTY_SESSION_MAP.write().await.insert(pty_id, vec![]); - } - - let mut pty_channel_writer = crate::PROCCESS_CHANNEL_TO_ID.write().await; - if pty_channel_writer.contains_key(&channel) { - drop(pty_channel_writer); - return Err(AnyError::new(Error::new( - ErrorKind::AlreadyExists, - "Channel already has a PTY/CMD", - ))); - } else { - pty_channel_writer.insert(channel, pty_id); - } - - drop(pty_channel_writer); - - crate::PROCCESS_WRITE_MESSAGES - .write() - .await - .insert(pty_id, queue.clone()); - - let (task, handle) = abortable(async move { - loop { - let task = queue.pop().await; - if let Err(err) = writer.write(task.as_bytes()) { - return err; - } - } - }); - - PTY_CANCELLATION_MAP.write().await.insert(pty_id, handle); - - tokio::spawn(async move { - match task.await { - Ok(err) => { - error!("Error occurred while passing writes to pty: {}", err) - } - Err(_) => { - let mut child = child_lock.lock().await; - match child.kill() { - Ok(_) => {} - Err(err) => { - warn!("Failed to kill pty child: {}", err) - } - } - drop(child); - } - } - }); - - Ok(pty_id) -} - -#[op] -async fn op_pty_add_session(id: u32, session: i32) -> Result<(), AnyError> { - PTY_SESSION_MAP - .write() - .await - .entry(id) - .and_modify(|sessions| sessions.push(session)); - Ok(()) -} - -#[op] -async fn op_pty_remove_session(id: u32, session: i32) -> Result<(), AnyError> { - PTY_SESSION_MAP - .write() - .await - .entry(id) - .and_modify(|sessions| { - if let Some(pos) = sessions.iter().position(|x| *x == session) { - sessions.swap_remove(pos); - } - }); - Ok(()) -} - -#[op] -async fn op_pty_write_msg(id: u32, msg: String) -> Result<(), AnyError> { - match crate::PROCCESS_WRITE_MESSAGES.read().await.get(&id) { - Some(queue) => { - queue.push(msg); - - Ok(()) - } - None => Err(AnyError::new(Error::new( - ErrorKind::NotFound, - format!("Couldn't find pty {} to write to", id), - ))), - } -} - -#[op] -async fn op_destroy_pty(id: u32, channel_id: i32) -> Result<(), AnyError> { - if let Some(cancel) = PTY_CANCELLATION_MAP.read().await.get(&id) { - cancel.abort(); - } else { - return Err(AnyError::new(Error::new( - ErrorKind::NotFound, - format!("Couldn't find pty {} to destroy", id), - ))); - } - - PTY_CANCELLATION_MAP.write().await.remove(&id); - PTY_SESSION_MAP.write().await.remove(&id); - crate::PROCCESS_WRITE_MESSAGES.write().await.remove(&id); - crate::PROCCESS_CHANNEL_TO_ID - .write() - .await - .remove(&channel_id); - - Ok(()) -} - -pub fn get_op_decls() -> Vec { - vec![ - op_destroy_pty::decl(), - op_register_pty::decl(), - op_pty_write_msg::decl(), - op_pty_add_session::decl(), - op_pty_remove_session::decl(), - ] -} diff --git a/src/deno_extension/quick_cmd.rs b/src/deno_extension/quick_cmd.rs deleted file mode 100644 index 529f52b..0000000 --- a/src/deno_extension/quick_cmd.rs +++ /dev/null @@ -1,96 +0,0 @@ -use homeval::goval; -use log::{error, warn}; -use std::{ - collections::{HashMap, VecDeque}, - io::Error, - process::Stdio, -}; - -use crate::channels::IPCMessage; - -use tokio::process::Command; - -use deno_core::{error::AnyError, op, OpDecl}; - -use crate::JsMessage; - -#[op] -async fn op_run_cmd( - _args: Vec, - channel: i32, - sessions: Vec, - _env: Option>, -) -> Result { - let mut env = crate::CHILD_PROCS_ENV_BASE.read().await.clone(); - - if let Some(env_vars) = _env { - env.extend(env_vars); - } - - let args = &mut VecDeque::from(_args.to_vec()); - let mut cmd = Command::new(VecDeque::pop_front(args).expect("Missing command")); - for arg in args { - cmd.arg(arg); - } - cmd.current_dir(std::env::current_dir()?); - - cmd.envs(env); - - cmd.stdout(Stdio::piped()); - cmd.stderr(Stdio::piped()); - - let child = cmd.spawn()?; - - let output = child.wait_with_output().await?; - // TODO: handle actual status - let mut status = 0; - - drop(cmd); - - // TODO: handle actual stderr - if output.stderr.len() > 0 { - status = 1; - error!(logs = String::from_utf8(output.stderr)?; "QUICK CMD STDERR"); - } - - let mut output_cmd = goval::Command::default(); - - output_cmd.body = Some(crate::goval::command::Body::Output(String::from_utf8( - output.stdout, - )?)); - output_cmd.channel = channel; - - for session in sessions.iter() { - if let Some(sender) = crate::SESSION_MAP.read().await.get(session) { - let mut to_send = output_cmd.clone(); - to_send.session = *session; - - sender.send(IPCMessage::from_cmd(to_send, *session))? - } else { - warn!( - session = session, channel = channel; - "Session missing when sending cmd output for channel" - ) - } - } - - let _read = crate::CHANNEL_MESSAGES.read().await; - if !_read.contains_key(&channel) { - return Err(AnyError::new(Error::new( - std::io::ErrorKind::NotFound, - "Cmd missing owning channel", - ))); - } - - let queue = _read.get(&channel).unwrap().clone(); - drop(_read); - - let exit_code = status; - queue.push(JsMessage::CmdDead(exit_code)); - - Ok(exit_code) -} - -pub fn get_op_decls() -> Vec { - vec![op_run_cmd::decl()] -} diff --git a/src/deno_extension/random.rs b/src/deno_extension/random.rs deleted file mode 100644 index 7174037..0000000 --- a/src/deno_extension/random.rs +++ /dev/null @@ -1,99 +0,0 @@ -use deno_core::{op, OpDecl}; -use serde::{Deserialize, Serialize}; - -use deno_core::error::AnyError; - -use log::{log, warn}; - -use std::time::{Duration, SystemTime, UNIX_EPOCH}; - -#[op] -fn op_time_milliseconds() -> String { - let timestamp = SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap_or(Duration::from_secs(0)); // Timestamp set to 0 if current time is before unix epoch - timestamp.as_millis().to_string() -} - -#[op(deferred)] -pub async fn op_sleep(millis: u64) -> Result<(), AnyError> { - tokio::time::sleep(Duration::from_millis(millis)).await; - Ok(()) -} - -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -pub enum ConsoleLogLevels { - Trace, - Debug, - Info, - Warn, - Error, -} - -impl ConsoleLogLevels { - pub fn to_log(&self) -> log::Level { - match self { - ConsoleLogLevels::Trace => log::Level::Trace, - ConsoleLogLevels::Debug => log::Level::Debug, - ConsoleLogLevels::Info => log::Level::Info, - ConsoleLogLevels::Warn => log::Level::Warn, - ConsoleLogLevels::Error => log::Level::Error, - } - } -} - -#[derive(Serialize, Deserialize, Clone, Debug)] -#[serde(rename_all = "camelCase")] -pub struct Service { - pub service: String, - pub name: Option, - pub id: i32, -} - -#[op] -fn op_console_log( - level: ConsoleLogLevels, - service: Service, - message: String, -) -> Result<(), AnyError> { - let mut name = "".to_string(); - match service.name { - None => {} - Some(_name) => { - name = format!(":{}", _name); - } - } - let target = &format!("homeval/v8: {}{}", service.service, name); - - log!( - target: target, - level.to_log(), - "{}", - message.replace("\\n", "\n") - ); - Ok(()) -} - -#[op] -fn op_get_env_var(key: String) -> Result, AnyError> { - match std::env::var(key.clone()) { - Ok(val) => Ok(Some(val)), - Err(e) => { - warn!("Error occured while fetching env var: '{}' {}", key, e); - Ok(None) - } - } -} - -pub fn get_op_decls() -> Vec { - vec![ - // Time - op_time_milliseconds::decl(), - op_sleep::decl(), - // Console - op_console_log::decl(), - // Env - op_get_env_var::decl(), - ] -} diff --git a/src/deno_extension/server_info.rs b/src/deno_extension/server_info.rs deleted file mode 100644 index fde5c49..0000000 --- a/src/deno_extension/server_info.rs +++ /dev/null @@ -1,69 +0,0 @@ -use crate::config::dotreplit::DotReplit; -use deno_core::{error::AnyError, op, OpDecl}; - -#[op] -fn op_server_name() -> Result { - Ok(env!("CARGO_PKG_NAME").to_string()) -} - -#[op] -fn op_server_version() -> Result { - Ok(env!("CARGO_PKG_VERSION").to_string()) -} - -#[op] -fn op_server_license() -> Result { - Ok(env!("CARGO_PKG_LICENSE").to_string()) -} - -#[op] -fn op_server_authors() -> Result { - Ok(env!("CARGO_PKG_AUTHORS").to_string()) -} - -#[op] -fn op_server_repository() -> Result { - Ok(env!("CARGO_PKG_REPOSITORY").to_string()) -} - -#[op] -fn op_server_description() -> Result { - Ok(env!("CARGO_PKG_DESCRIPTION").to_string()) -} - -#[op] -fn op_server_uptime() -> Result { - Ok(crate::START_TIME.elapsed().as_secs()) -} - -#[op] -fn op_get_supported_services() -> Result, AnyError> { - Ok(crate::IMPLEMENTED_SERVICES.clone()) -} - -#[op] -fn op_get_dotreplit_config() -> Result { - Ok(crate::DOTREPLIT_CONFIG.clone()) -} - -#[op] -fn op_get_running_os() -> Result { - Ok(std::env::consts::OS.to_string()) -} - -pub fn get_op_decls() -> Vec { - vec![ - op_server_name::decl(), - op_server_version::decl(), - op_server_license::decl(), - op_server_authors::decl(), - op_server_repository::decl(), - op_server_description::decl(), - op_server_uptime::decl(), - op_get_supported_services::decl(), - // Config - op_get_dotreplit_config::decl(), - // System info - op_get_running_os::decl(), - ] -} diff --git a/src/deno_extension/sysinfo.rs b/src/deno_extension/sysinfo.rs deleted file mode 100644 index 0ceb375..0000000 --- a/src/deno_extension/sysinfo.rs +++ /dev/null @@ -1,81 +0,0 @@ -use deno_core::{error::AnyError, op, OpDecl}; -use serde::Serialize; -// use sysinfo::{self, CpuRefreshKind, RefreshKind, SystemExt}; -use systemstat::{Platform, System}; -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -pub struct CpuInfo {} - -#[op] -async fn op_cpu_info() -> Result { - tokio::task::spawn_blocking(move || Ok(crate::CPU_STATS.elapsed().as_nanos().to_string())) - .await? -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -pub struct MemoryInfo { - total: u64, - free: u64, -} - -#[op] -async fn op_memory_info() -> Result { - let info = tokio::task::spawn_blocking(move || -> std::io::Result { - match System::new().memory() { - Ok(mem) => Ok(MemoryInfo { - total: mem.total.as_u64(), - free: mem.free.as_u64(), - }), - Err(_) => Ok(MemoryInfo { total: 0, free: 0 }), - } - }) - .await??; - - Ok(info) -} - -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -pub struct DiskInfo { - available: u64, - total: u64, - free: u64, -} - -#[op] -async fn op_disk_info() -> Result { - let info = tokio::task::spawn_blocking(move || -> std::io::Result { - match System::new().mount_at("/") { - Ok(disk) => { - let mut info = DiskInfo { - available: 0, - total: 0, - free: 0, - }; - - info.available += disk.avail.as_u64(); - info.total += disk.total.as_u64(); - info.free += disk.free.as_u64(); - - Ok(info) - } - Err(_) => Ok(DiskInfo { - available: 0, - total: 0, - free: 0, - }), - } - }) - .await??; - - Ok(info) -} - -pub fn get_op_decls() -> Vec { - vec![ - op_cpu_info::decl(), - op_memory_info::decl(), - op_disk_info::decl(), - ] -} diff --git a/types/homeval-types/package.json b/types/homeval-types/package.json deleted file mode 100644 index 67207e6..0000000 --- a/types/homeval-types/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "homeval-types", - "version": "0.0.1", - "description": "Type definitions for homeval's js bridge", - "types": "types.d.ts", - "files": [ - "types.d.ts" - ], - "private": true -} diff --git a/types/homeval-types/types.d.ts b/types/homeval-types/types.d.ts deleted file mode 100644 index 16c8a0a..0000000 --- a/types/homeval-types/types.d.ts +++ /dev/null @@ -1,218 +0,0 @@ -import { replit } from "@replit/protocol"; - -type DotReplit = { - run?: Exec, - language?: string, - entrypoint?: string, - languages?: { [id: string]: DotReplitLanguage }, - hidden?: string[] -} - -type DotReplitLanguage = { - pattern?: string, - syntax?: string, - languageServer: LanguageServerConfig, -} - -type LanguageServerConfig = { - start?: Exec, - configurationJson?: string, - initializationOptionsJson?: string, -} - -type ExecLifecycle = "NonBlocking" | "Stdin" | "Blocking"; - -type Exec = { - args?: string[], - env?: { [id: string]: string }, - blocking?: boolean, - // TODO: confirm if this is actually how it is returned - lifecycle?: ExecLifecycle, - split_stderr?: boolean, - split_logs?: boolean, -} - -type ReplspaceMessage = { - githubTokenReq?: string, - openFileReq?: [string, boolean, string], - openMultipleFiles?: [string[], string], - - githubTokenRes?: string, - openFileRes?: {}, -} - -type DatabaseFile = { - name: string, - crc32: number, - contents: string, - history: string[], -} - -declare global { - // [goval::generated::globals] (generated on the fly) - - let serviceInfo: { - id: number, - service: string, - name: string | null, - } - - // [goval::api.js] (api.js) - - let api: typeof replit.goval.api; - let Buffer: typeof import("buffer").Buffer; - let protobufjs: typeof import("protobufjs"); - let CRC32: typeof import("crc-32"); - - // [goval::runtime.js] (src/runtime.js) - - namespace fs { - function stat(path: string): Promise<{ - exists: boolean, - type: "file" | "directory" | "symlink", - size: number, - fileMode: string, - modTime: number, - }>; - function readDir(path: string): Promise<{ - path: string, - type: "file" | "directory" | "symlink" - }[]>; - function makeDir(path: string): Promise; - function writeFile(path: string, contents: number[]): Promise; - function writeFileString(path: string, contents: string): Promise; - function readFile(path: string): Promise; - function readFileString(path: string): Promise; - function remove(path: string): Promise; - function rename(oldPath: string, newPath: string): Promise; - } - - // @ts-ignore - namespace Date { - function now(): BigInt; - } - - class ServiceBase { - id: number - name: string - service: string - clients: number[] - _online: boolean - - constructor(id: number, service: string, name: string | null) - - stop(): Promise - start(): Promise - ipc_recv(): Promise - - _recv(message: { ipc: { bytes: number[], session: number } }): Promise - recv(command: replit.goval.api.Command, session: number): Promise - - _send(cmd: replit.goval.api.Command, session: number): Promise - send(cmd: replit.goval.api.Command, session: number): Promise - - _attach(session: number): Promise - attach(session: number): Promise - - _detach(session: number, forced: boolean): Promise - detach(session: number, forced: boolean): Promise - - process_died(proc_id: number, exit_code: number): Promise - - on_replspace(session: number, msg: ReplspaceMessage): Promise - replspace_reply(nonce: string, message: ReplspaceMessage): Promise - } - - class Process { - channel: number - id: number - command: string - args: string[] - - constructor(channel: number, command: string, args: string[], env_vars: { [id: string]: string }) - - init(sessions: number[] | undefined): Promise - destroy(): Promise - add_session(session: number): Promise - remove_session(session: number): Promise - write(input: string): Promise - _await_pty_exists(): Promise - } - - class PtyProcess extends Process { } - - type FileEvent = { - remove?: string, - create?: String, - modify?: String, - rename?: [string, string], - err?: string - }; - class FileWatcher { - id: number - online: boolean - watched_files: number - listeners: ((event: FileEvent) => Promise)[] - - constructor() - - init(): Promise - - watch(paths: string[]): Promise - - add_listener(listener: (event: FileEvent) => Promise): null - - stop(): Promise - start(): Promise - - _await_watcher_exists(): Promise - } - - namespace process { - namespace system { - function cpuTime(): Promise; - function memoryUsage(): Promise<{ - total: number, - free: number - }>; - function diskUsage(): Promise<{ - available: number, - total: number, - free: number - }>; - let os: string; - } - - namespace database { - let _supported: boolean; - const supported: boolean; - - function getFile(name: string): Promise; - function setFile(file_model: DatabaseFile): Promise; - } - - namespace server { - function name(): string; - function version(): string; - function license(): string; - function repository(): string; - function description(): string; - function services(): string[]; - function authors(): string[]; - function uptime(): number; - } - - let env: { [id: string]: string | null } - - function getUserInfo(session: number): Promise<{ username: string, id: number }> - function getDotreplitConfig(): DotReplit - - function quickCommand(args: string[], channel: number, sessions: number[], env: { [id: string]: string }): Promise - } - - function diffText(old_text: string, new_text: string): Promise<{ - insert?: string, - delete?: number, - skip?: number, - }[]> -} \ No newline at end of file From f5568a39ad62e63f7cf4a1b3d128c18966b35b78 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sun, 8 Oct 2023 19:06:24 -0700 Subject: [PATCH 018/103] fix(services): Fix pty impl Makes the PTY implementation react to a process exiting correctly, the previous method had issues in certain scenarios. --- services/src/types/pty.rs | 88 +++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/services/src/types/pty.rs b/services/src/types/pty.rs index 24ca9de..1a7101e 100644 --- a/services/src/types/pty.rs +++ b/services/src/types/pty.rs @@ -1,10 +1,11 @@ // use futures_util::{future::abortable, stream::AbortHandle}; use log::{as_display, as_error, error}; -use portable_pty::{Child, PtySize}; +use portable_pty::{Child, PtyPair, PtySize}; use std::{ collections::{HashMap, VecDeque}, io::{Error, ErrorKind, Write}, sync::{atomic::AtomicBool, Arc}, + time::Duration, }; use crate::ChannelMessage; @@ -95,6 +96,7 @@ pub struct Pty { cancelled: Arc, child_lock: Arc>>, scrollback: Arc>, + pair: PtyPair, } impl Pty { @@ -147,7 +149,6 @@ impl Pty { let child_lock = Arc::new(Mutex::new(child)); - let child_lock_reaper = child_lock.clone(); let cancelled = Arc::new(AtomicBool::new(false)); let scrollback = Arc::new(RwLock::new(String::new())); let mut pty_writer = PtyWriter { @@ -159,43 +160,54 @@ impl Pty { let contact_clone = contact.clone(); tokio::task::spawn(async move { - match tokio::task::spawn(async move { - if let Err(err) = - tokio::task::spawn_blocking(move || std::io::copy(&mut reader, &mut pty_writer)) - .await - { - error!("Error occurred copying from pty to channels: {}", err); - }; - - // let _read = crate::CHANNEL_MESSAGES.read().await; - // if !_read.contains_key(&channel) { - // return Err(format_err!("Owning channel")); - // } - - let exit_code; - - if let Some(code) = child_lock_reaper.lock().await.try_wait()? { - exit_code = code.exit_code() as i32; - } else { - exit_code = 0; - } + if let Err(err) = + tokio::task::spawn_blocking(move || std::io::copy(&mut reader, &mut pty_writer)) + .await + { + error!("Error occurred copying from pty to channels: {}", err); + }; - // let queue = _read.get(&channel).unwrap().clone(); - // drop(_read); - contact_clone.send(ChannelMessage::ProcessDead(exit_code))?; + // let _read = crate::CHANNEL_MESSAGES.read().await; + // if !_read.contains_key(&channel) { + // return Err(format_err!("Owning channel")); + // } + }); + + let child_lock_reaper = child_lock.clone(); + tokio::task::spawn(async move { + match tokio::task::spawn(async move { + let mut interval = tokio::time::interval(Duration::from_millis(50)); - Ok::<(), anyhow::Error>(()) + loop { + interval.tick().await; + let mut child_ = child_lock_reaper.lock().await; + if let Some(exit_code) = child_.try_wait()? { + return Ok::(exit_code.exit_code() as i32); + } + drop(child_); + } }) .await { - Ok(res) => match res { - Ok(_) => {} - Err(err) => { - error!(err = as_display!(err); "PTY child death alert error"); + Ok(res) => { + match res { + Ok(exit_code) => { + // let queue = _read.get(&channel).unwrap().clone(); + // drop(_read); + match contact_clone.send(ChannelMessage::ProcessDead(exit_code)) { + Ok(_) => {} + Err(err) => { + error!(err = as_error!(err); "PTY child proc reaper errored when alerting channel") + } + } + } + Err(err) => { + error!(err = as_display!(err); "PTY child proc reaper errored") + } } - }, + } Err(err) => { - error!(err = as_error!(err); "Join error in pty"); + error!(err = as_error!(err); "Join error on pty child proc reaper") } } }); @@ -225,10 +237,22 @@ impl Pty { cancelled, child_lock, scrollback, + pair, }; Ok(pty) } + // TODO: use spawn_blocking, bcuz interacting with sync code + pub fn resize(&mut self, rows: u16, cols: u16) -> Result<()> { + self.pair.master.resize(PtySize { + rows, + cols, + pixel_width: 0, + pixel_height: 0, + })?; + Ok(()) + } + pub async fn cancel(&mut self) -> Result<()> { self.cancelled .store(true, std::sync::atomic::Ordering::SeqCst); From 1ff4f522684341f73daf898cceef6e9fe40d8cdc Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sun, 8 Oct 2023 19:06:56 -0700 Subject: [PATCH 019/103] feat(services): Implement shell service --- services/src/lib.rs | 25 +++++++------ services/src/shell.rs | 84 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 services/src/shell.rs diff --git a/services/src/lib.rs b/services/src/lib.rs index 805a052..f025e15 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -3,6 +3,7 @@ mod gcsfiles; mod ot; mod output; mod presence; +mod shell; mod snapshot; mod stub; mod toolchain; @@ -33,13 +34,24 @@ impl Channel { dotreplit: Arc>, sender: tokio::sync::mpsc::UnboundedSender, ) -> Result { + let info = ChannelInfo { + id, + name, + service: service.clone(), + clients: HashMap::new(), + sessions: HashMap::new(), + sender: sender.clone(), + dotreplit, + }; + let channel: Box = match service.as_str() { "chat" => Box::new(chat::Chat::new()), "gcsfiles" => Box::new(gcsfiles::GCSFiles {}), "presence" => Box::new(presence::Presence::new()), - "ot" => Box::new(ot::OT::new(sender.clone()).await?), + "ot" => Box::new(ot::OT::new(sender).await?), "snapshot" => Box::new(snapshot::Snapshot {}), "output" => Box::new(output::Output::new().await), + "shell" => Box::new(shell::Shell::new(&info).await?), "toolchain" => Box::new(toolchain::Toolchain {}), "null" => Box::new(stub::Stub {}), // This channel never does anything "open" => Box::new(stub::Stub {}), // Stub until infra is set up to handle this @@ -47,16 +59,6 @@ impl Channel { _ => return Err(format_err!("Unknown service: {}", service)), }; - let info = ChannelInfo { - id, - name, - service, - clients: HashMap::new(), - sessions: HashMap::new(), - sender, - dotreplit, - }; - Ok(Channel { info, _inner: channel, @@ -152,5 +154,6 @@ pub static IMPLEMENTED_SERVICES: &[&str] = &[ "git", "open", "output", + "shell", "toolchain", ]; diff --git a/services/src/shell.rs b/services/src/shell.rs new file mode 100644 index 0000000..9ad0a88 --- /dev/null +++ b/services/src/shell.rs @@ -0,0 +1,84 @@ +pub struct Shell { + pty: Pty, +} +use std::sync::Arc; + +use async_trait::async_trait; +use log::{as_debug, debug}; +use tokio::sync::RwLock; + +use super::traits; +use super::types::pty::Pty; +use crate::{ClientInfo, IPCMessage}; +use anyhow::{format_err, Result}; + +#[async_trait] +impl traits::Service for Shell { + async fn attach( + &mut self, + _info: &super::types::ChannelInfo, + _client: ClientInfo, + session: i32, + sender: tokio::sync::mpsc::UnboundedSender, + ) -> Result> { + self.pty.session_join(session, sender).await?; + Ok(None) + } + + async fn detach(&mut self, _info: &super::types::ChannelInfo, session: i32) -> Result<()> { + self.pty.session_leave(session).await?; + Ok(()) + } + + async fn message( + &mut self, + _info: &super::types::ChannelInfo, + message: goval::Command, + _session: i32, + ) -> Result> { + let body = match message.body.clone() { + None => return Err(format_err!("Expected command body")), + Some(body) => body, + }; + + match body { + goval::command::Body::Input(msg) => { + self.pty.write(msg)?; + } + goval::command::Body::ResizeTerm(size) => { + self.pty.resize(size.rows as u16, size.cols as u16)? + } + _ => { + debug!(msg = as_debug!(message); "New message"); + } + } + Ok(None) + } + + async fn proccess_died( + &mut self, + info: &super::types::ChannelInfo, + _exit_code: i32, + ) -> Result<()> { + self.pty = Shell::start_pty(info).await?; + Ok(()) + } +} + +impl Shell { + async fn start_pty(info: &super::types::ChannelInfo) -> Result { + Ok(Pty::start( + vec![std::env::var("SHELL").unwrap_or("bash".to_string())], + info.id, + Arc::new(RwLock::new(info.clients.clone())), + info.sender.clone(), + None, + ) + .await?) + } + pub async fn new(info: &super::types::ChannelInfo) -> Result { + Ok(Shell { + pty: Shell::start_pty(info).await?, + }) + } +} From ba23e63dde9af2233493a67cb8941ec8eb0e8aad Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sun, 8 Oct 2023 20:59:12 -0700 Subject: [PATCH 020/103] refactor(services): Remove useless code in gcsfiles --- services/src/gcsfiles.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/src/gcsfiles.rs b/services/src/gcsfiles.rs index a43bb8e..8365d62 100644 --- a/services/src/gcsfiles.rs +++ b/services/src/gcsfiles.rs @@ -70,7 +70,7 @@ impl traits::Service for GCSFiles { "repository": "https://github.com/goval-community/homeval", "description": "", // TODO: do dis "uptime": 0, // TODO: impl fo realz - "services": super::IMPLEMENTED_SERVICES.clone() + "services": super::IMPLEMENTED_SERVICES }); val.to_string().as_bytes().to_vec() From cb611e2b86edad0e59977122c07fd031cadf5e11 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sun, 8 Oct 2023 21:00:45 -0700 Subject: [PATCH 021/103] feat(services): Platform specific default shell --- services/src/shell.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/services/src/shell.rs b/services/src/shell.rs index 9ad0a88..9eeebc1 100644 --- a/services/src/shell.rs +++ b/services/src/shell.rs @@ -65,10 +65,15 @@ impl traits::Service for Shell { } } +#[cfg(target_family = "unix")] +static DEFAULT_SHELL: &'static str = "sh"; +#[cfg(target_family = "windows")] +static DEFAULT_SHELL: &'static str = "pwsh"; + impl Shell { async fn start_pty(info: &super::types::ChannelInfo) -> Result { Ok(Pty::start( - vec![std::env::var("SHELL").unwrap_or("bash".to_string())], + vec![std::env::var("SHELL").unwrap_or(DEFAULT_SHELL.to_string())], info.id, Arc::new(RwLock::new(info.clients.clone())), info.sender.clone(), From 1d322ab959b2fb27c848c2d6d9746adc735e2851 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sun, 8 Oct 2023 22:02:44 -0700 Subject: [PATCH 022/103] feat(replspace): Fix replspace implementation --- Cargo.toml | 2 +- services/src/lib.rs | 9 ++++- services/src/output.rs | 6 ++- services/src/shell.rs | 6 ++- services/src/traits.rs | 13 ++++++- services/src/types/messaging.rs | 3 +- src/goval_server.rs | 1 + src/main.rs | 3 ++ src/replspace_server.rs | 65 +++++++++++++++------------------ 9 files changed, 64 insertions(+), 44 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6199e84..c7fd96e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ See https://govaldocs.pages.dev""" members = [".", "migration", "entity", "services", "protobuf"] [features] -default = [] #"replspace", "database", "repldb", "verify_connections"] +default = ["replspace"] #"replspace", "database", "repldb", "verify_connections"] repldb = ["database"] database = ["dep:sea-orm", "dep:sea-query", "dep:migration", "dep:entity"] replspace = [] diff --git a/services/src/lib.rs b/services/src/lib.rs index f025e15..ee46323 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -1,5 +1,6 @@ mod chat; mod gcsfiles; +mod git; mod ot; mod output; mod presence; @@ -53,9 +54,9 @@ impl Channel { "output" => Box::new(output::Output::new().await), "shell" => Box::new(shell::Shell::new(&info).await?), "toolchain" => Box::new(toolchain::Toolchain {}), + "git" => Box::new(git::Git::new()), "null" => Box::new(stub::Stub {}), // This channel never does anything "open" => Box::new(stub::Stub {}), // Stub until infra is set up to handle this - "git" => Box::new(stub::Stub {}), // Stub until replspace api is fixed _ => return Err(format_err!("Unknown service: {}", service)), }; @@ -77,7 +78,11 @@ impl Channel { self._inner.proccess_died(&self.info, exit_code).await } ChannelMessage::CmdDead(_) => todo!(), - ChannelMessage::Replspace(_, _) => todo!(), + ChannelMessage::Replspace(session, msg, respond) => { + self._inner + .replspace(&self.info, msg, session, respond) + .await + } ChannelMessage::Shutdown => match self._inner.shutdown(&self.info).await { Ok(_) => break, Err(err) => { diff --git a/services/src/output.rs b/services/src/output.rs index da9ab00..140eb77 100644 --- a/services/src/output.rs +++ b/services/src/output.rs @@ -3,6 +3,7 @@ pub struct Output { start_time: Option, } use std::{ + collections::HashMap, sync::Arc, time::{SystemTime, UNIX_EPOCH}, vec, @@ -90,13 +91,16 @@ impl traits::Service for Output { } } + let mut env = HashMap::new(); + env.insert("REPLIT_GIT_TOOLS_CHANNEL_FROM".into(), info.id.to_string()); + self.pty = Some( Pty::start( cmd, info.id, Arc::new(RwLock::new(info.clients.clone())), info.sender.clone(), - None, + Some(env), ) .await?, ); diff --git a/services/src/shell.rs b/services/src/shell.rs index 9eeebc1..d81dad0 100644 --- a/services/src/shell.rs +++ b/services/src/shell.rs @@ -1,7 +1,7 @@ pub struct Shell { pty: Pty, } -use std::sync::Arc; +use std::{collections::HashMap, sync::Arc}; use async_trait::async_trait; use log::{as_debug, debug}; @@ -72,12 +72,14 @@ static DEFAULT_SHELL: &'static str = "pwsh"; impl Shell { async fn start_pty(info: &super::types::ChannelInfo) -> Result { + let mut env = HashMap::new(); + env.insert("REPLIT_GIT_TOOLS_CHANNEL_FROM".into(), info.id.to_string()); Ok(Pty::start( vec![std::env::var("SHELL").unwrap_or(DEFAULT_SHELL.to_string())], info.id, Arc::new(RwLock::new(info.clients.clone())), info.sender.clone(), - None, + Some(env), ) .await?) } diff --git a/services/src/traits.rs b/services/src/traits.rs index 13ba214..9db0464 100644 --- a/services/src/traits.rs +++ b/services/src/traits.rs @@ -1,7 +1,8 @@ use anyhow::Result; use async_trait::async_trait; +use tokio::sync::mpsc::Sender; -use crate::{ClientInfo, FSEvent, IPCMessage}; +use crate::{ClientInfo, FSEvent, IPCMessage, ReplspaceMessage}; #[async_trait] pub(crate) trait Service { @@ -29,6 +30,16 @@ pub(crate) trait Service { Ok(()) } + async fn replspace( + &mut self, + _info: &super::types::ChannelInfo, + _msg: ReplspaceMessage, + _session: i32, + _respond: Option>, + ) -> Result<()> { + Ok(()) + } + async fn fsevent(&mut self, _info: &super::types::ChannelInfo, _event: FSEvent) -> Result<()> { Ok(()) } diff --git a/services/src/types/messaging.rs b/services/src/types/messaging.rs index 0e30662..2fede0f 100644 --- a/services/src/types/messaging.rs +++ b/services/src/types/messaging.rs @@ -3,6 +3,7 @@ use goval; use prost::Message; use serde; use serde::{Deserialize, Serialize}; +use tokio::sync::mpsc::Sender; use super::client::ClientInfo; @@ -29,7 +30,7 @@ pub enum ChannelMessage { ProcessDead(i32), CmdDead(i32), FSEvent(super::FSEvent), - Replspace(i32, ReplspaceMessage), // session, message + Replspace(i32, ReplspaceMessage, Option>), // session, message Shutdown, // Shutdown the service, value has to be true so that runtime.js can match it in an if check } diff --git a/src/goval_server.rs b/src/goval_server.rs index 940d454..2c52b09 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -406,6 +406,7 @@ async fn detach_channel(channel: i32, session: i32, forced: bool) -> Result<()> tokio::spawn(async move { CHANNEL_METADATA.write().await.remove(&channel); CHANNEL_SESSIONS.write().await.remove(&channel); + CHANNEL_MESSAGES.write().await.remove(&channel); PROCCESS_CHANNEL_TO_ID.write().await.remove(&channel); LAST_SESSION_USING_CHANNEL.write().await.remove(&channel); }); diff --git a/src/main.rs b/src/main.rs index 7767dd8..a7c8cdb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,6 +9,7 @@ use tokio::sync::{mpsc, Mutex, RwLock}; use homeval_services::{ config::dotreplit::DotReplit, + messaging::ReplspaceMessage, ChannelMessage, ClientInfo, IPCMessage, @@ -85,6 +86,8 @@ async fn main() -> Result<(), Error> { debug!("Lazy statics initialized successfully"); + std::env::set_var("HOMEVAL_START_DIR", std::env::current_dir()?); + // console_subscriber::init(); let _ = env_logger::try_init().unwrap(); diff --git a/src/replspace_server.rs b/src/replspace_server.rs index d7901c8..0fb55f9 100644 --- a/src/replspace_server.rs +++ b/src/replspace_server.rs @@ -5,10 +5,10 @@ use axum::{ routing::{get, post}, Json, Router, }; -use log::{as_debug, as_error, debug, error, info}; +use log::{as_debug, debug, error, info}; use serde::{Deserialize, Serialize}; use textnonce::TextNonce; -use tokio::sync::oneshot::channel; +use tokio::sync::mpsc::channel; use crate::{ChannelMessage, ReplspaceMessage}; @@ -55,33 +55,26 @@ async fn get_gh_token(_query: Option>) -> (StatusCode, Jso } let nonce = TextNonce::new().into_string(); - let (tx, rx) = channel(); + let (tx, mut rx) = channel(1); - let mut callback_table = crate::REPLSPACE_CALLBACKS.write().await; - - callback_table.insert(nonce.clone(), Some(tx)); - - drop(callback_table); - - let to_send = ChannelMessage::Replspace(session, ReplspaceMessage::GithubTokenReq(nonce)); + let to_send = + ChannelMessage::Replspace(session, ReplspaceMessage::GithubTokenReq(nonce), Some(tx)); let msg_lock = crate::CHANNEL_MESSAGES.read().await; for channel in msg_lock.values() { channel.send(to_send.clone()).expect("TODO: deal with this"); } - // let queue = msg_lock.get(&cmd.channel).unwrap().clone(); drop(msg_lock); let res; - match rx.await { - Ok(token) => res = token, - Err(err) => { - error!( - error = as_error!(err); - "Got error awaiting replspace api github token fetcher callback" - ); + let msg = rx.recv().await; + rx.close(); + match msg { + Some(token) => res = token, + None => { + error!("rx#recv() returned None in gh get token"); return ( StatusCode::INTERNAL_SERVER_ERROR, Json(GithubTokenRes { @@ -154,24 +147,20 @@ async fn open_file(Json(query): Json) -> (StatusCode, Json) -> (StatusCode, Json) -> (StatusCode, Json res = token, - Err(err) => { - error!( - error = as_error!(err); - "Got error awaiting replspace api open file fetcher callback" - ); + let msg = rx.recv().await; + rx.close(); + match msg { + Some(token) => { + res = token; + } + None => { + error!("rx#none() returned none in replspace api open file fetcher"); return ( StatusCode::INTERNAL_SERVER_ERROR, Json(OpenFileRes { From cb62722ed3cda4385d81b3324ab0d2089ac0f0bd Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sun, 8 Oct 2023 22:03:01 -0700 Subject: [PATCH 023/103] feat(services): Implement git service --- services/src/git.rs | 112 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 services/src/git.rs diff --git a/services/src/git.rs b/services/src/git.rs new file mode 100644 index 0000000..10bc399 --- /dev/null +++ b/services/src/git.rs @@ -0,0 +1,112 @@ +pub struct Git { + replspace: HashMap>>, +} +use std::collections::HashMap; + +use crate::ReplspaceMessage; + +use super::traits; +use anyhow::{format_err, Result}; +use async_trait::async_trait; +use log::{as_debug, warn}; +use tokio::sync::mpsc::Sender; + +#[async_trait] +impl traits::Service for Git { + async fn message( + &mut self, + _info: &super::types::ChannelInfo, + message: goval::Command, + _session: i32, + ) -> Result> { + let body = match message.body.clone() { + None => return Err(format_err!("Expected command body")), + Some(body) => body, + }; + + match body { + goval::command::Body::ReplspaceApiGitHubToken(token) => { + match self.replspace.get(&token.nonce) { + Some(_respond) => { + if let Some(respond) = _respond { + respond + .send(ReplspaceMessage::GithubTokenRes(token.token)) + .await?; + } + } + None => { + warn!(msg = as_debug!(message), nonce = token.nonce; "Missing replspace response callback for github token"); + } + } + } + goval::command::Body::ReplspaceApiCloseFile(close) => { + match self.replspace.get(&close.nonce) { + Some(_respond) => { + if let Some(respond) = _respond { + respond.send(ReplspaceMessage::OpenFileRes).await?; + } + } + None => { + warn!(msg = as_debug!(message), nonce = close.nonce; "Missing replspace response callback for close file"); + } + } + } + _ => {} + } + + Ok(None) + } + + async fn replspace( + &mut self, + info: &super::types::ChannelInfo, + msg: ReplspaceMessage, + session: i32, + respond: Option>, + ) -> Result<()> { + if session == 0 { + warn!(msg = as_debug!(msg); "Got replspace message from an unknown session, ignoring"); + return Ok(()); + } + + match msg { + ReplspaceMessage::GithubTokenReq(nonce) => { + let mut token_req = goval::Command::default(); + token_req.body = Some(goval::command::Body::ReplspaceApiGetGitHubToken( + goval::ReplspaceApiGetGitHubToken { + nonce: nonce.clone(), + }, + )); + info.send(token_req, crate::SendSessions::Only(session)) + .await?; + + self.replspace.insert(nonce, respond); + } + ReplspaceMessage::OpenFileReq(path, wait_for_close, nonce) => { + let mut token_req = goval::Command::default(); + token_req.body = Some(goval::command::Body::ReplspaceApiOpenFile( + goval::ReplspaceApiOpenFile { + nonce: nonce.clone(), + wait_for_close, + file: path, + }, + )); + info.send(token_req, crate::SendSessions::Only(session)) + .await?; + + self.replspace.insert(nonce, respond); + } + _ => {} + } + + Ok(()) + } +} + +impl Git { + pub fn new() -> Git { + Git { + replspace: HashMap::new(), + } + } +} From a48656fbdd31f8835ed29cca251363872fa9a429 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sun, 8 Oct 2023 22:17:33 -0700 Subject: [PATCH 024/103] feat(services): Implement dotreplit service --- services/src/dotreplit.rs | 36 ++++++++++++++++++++++++++++++++++++ services/src/lib.rs | 3 +++ 2 files changed, 39 insertions(+) create mode 100644 services/src/dotreplit.rs diff --git a/services/src/dotreplit.rs b/services/src/dotreplit.rs new file mode 100644 index 0000000..ae33cbb --- /dev/null +++ b/services/src/dotreplit.rs @@ -0,0 +1,36 @@ +pub struct DotReplit {} +use super::traits; + +use anyhow::{format_err, Result}; +use async_trait::async_trait; + +#[async_trait] +impl traits::Service for DotReplit { + async fn message( + &mut self, + _info: &super::types::ChannelInfo, + message: goval::Command, + _session: i32, + ) -> Result> { + let body = match message.body.clone() { + None => return Err(format_err!("Expected command body")), + Some(body) => body, + }; + + match body { + goval::command::Body::DotReplitGetRequest(_) => { + let mut dotreplit = goval::Command::default(); + let inner: goval::DotReplit = _info.dotreplit.read().await.clone().into(); + + dotreplit.body = Some(goval::command::Body::DotReplitGetResponse( + goval::DotReplitGetResponse { + dot_replit: Some(inner), + }, + )); + + Ok(Some(dotreplit)) + } + _ => Ok(None), + } + } +} diff --git a/services/src/lib.rs b/services/src/lib.rs index ee46323..ab95e1d 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -1,4 +1,5 @@ mod chat; +mod dotreplit; mod gcsfiles; mod git; mod ot; @@ -55,6 +56,7 @@ impl Channel { "shell" => Box::new(shell::Shell::new(&info).await?), "toolchain" => Box::new(toolchain::Toolchain {}), "git" => Box::new(git::Git::new()), + "dotreplit" => Box::new(dotreplit::DotReplit {}), "null" => Box::new(stub::Stub {}), // This channel never does anything "open" => Box::new(stub::Stub {}), // Stub until infra is set up to handle this _ => return Err(format_err!("Unknown service: {}", service)), @@ -161,4 +163,5 @@ pub static IMPLEMENTED_SERVICES: &[&str] = &[ "output", "shell", "toolchain", + "dotreplit", ]; From 2ad2469132e5e1cdb5f055dd67cc3bc9dc1d22b3 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 9 Oct 2023 17:45:34 -0700 Subject: [PATCH 025/103] refactor: Make code follow clippy default lint rules --- Cargo.toml | 2 +- protobuf/src/lib.rs | 1 + services/src/gcsfiles.rs | 56 +++++++++------ services/src/git.rs | 32 +++++---- services/src/lib.rs | 10 ++- services/src/ot.rs | 108 +++++++++++++++++------------ services/src/output.rs | 32 +++++---- services/src/presence.rs | 37 +++++----- services/src/shell.rs | 8 +-- services/src/snapshot.rs | 6 +- services/src/toolchain.rs | 35 ++++++---- services/src/types/channel_info.rs | 4 +- services/src/types/config.rs | 50 ++++++------- services/src/types/pty.rs | 23 +++--- src/goval_server.rs | 86 ++++++++++++----------- src/main.rs | 4 +- src/parse_paseto.rs | 3 +- src/replspace_server.rs | 32 ++++----- 18 files changed, 290 insertions(+), 239 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c7fd96e..3178e0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,7 @@ See https://govaldocs.pages.dev""" members = [".", "migration", "entity", "services", "protobuf"] [features] -default = ["replspace"] #"replspace", "database", "repldb", "verify_connections"] +default = ["replspace"] # "database", "repldb", "verify_connections"] repldb = ["database"] database = ["dep:sea-orm", "dep:sea-query", "dep:migration", "dep:entity"] replspace = [] diff --git a/protobuf/src/lib.rs b/protobuf/src/lib.rs index 2a39db9..f4a1201 100644 --- a/protobuf/src/lib.rs +++ b/protobuf/src/lib.rs @@ -1,2 +1,3 @@ +#![allow(clippy::all)] // Include the `goval` module, which is generated from goval.proto. include!(concat!(env!("OUT_DIR"), "/goval.rs")); diff --git a/services/src/gcsfiles.rs b/services/src/gcsfiles.rs index 8365d62..5a17b37 100644 --- a/services/src/gcsfiles.rs +++ b/services/src/gcsfiles.rs @@ -45,15 +45,16 @@ impl traits::Service for GCSFiles { } let mut ret = goval::Command::default(); - let mut _inner = goval::Files::default(); - _inner.files = res; + let _inner = goval::Files { files: res }; ret.body = Some(goval::command::Body::Files(_inner)); Ok(Some(ret)) } goval::command::Body::Mkdir(dir) => { fs::create_dir_all(dir.path).await?; - let mut ret = goval::Command::default(); - ret.body = Some(goval::command::Body::Ok(goval::Ok {})); + let ret = goval::Command { + body: Some(goval::command::Body::Ok(goval::Ok {})), + ..Default::default() + }; Ok(Some(ret)) } goval::command::Body::Read(file) => { @@ -78,11 +79,13 @@ impl traits::Service for GCSFiles { _ => match fs::read(&file.path).await { Err(err) => { warn!(error = as_error!(err); "Error reading file in gcsfiles"); - let mut ret = goval::Command::default(); - ret.body = Some(goval::command::Body::Error(format!( - "{}: no such file or directory", - file.path - ))); + let ret = goval::Command { + body: Some(goval::command::Body::Error(format!( + "{}: no such file or directory", + file.path + ))), + ..Default::default() + }; return Ok(Some(ret)); } @@ -91,9 +94,11 @@ impl traits::Service for GCSFiles { }; let mut ret = goval::Command::default(); - let mut _inner = goval::File::default(); - _inner.content = contents; - _inner.path = file.path; + let mut _inner = goval::File { + content: contents, + path: file.path, + ..Default::default() + }; ret.body = Some(goval::command::Body::File(_inner)); Ok(Some(ret)) } @@ -105,21 +110,28 @@ impl traits::Service for GCSFiles { fs::remove_file(&file.path).await? } - let mut ret = goval::Command::default(); - ret.body = Some(goval::command::Body::Ok(goval::Ok {})); + let ret = goval::Command { + body: Some(goval::command::Body::Ok(goval::Ok {})), + ..Default::default() + }; Ok(Some(ret)) } goval::command::Body::Move(move_req) => { fs::rename(move_req.old_path, move_req.new_path).await?; - let mut ret = goval::Command::default(); - ret.body = Some(goval::command::Body::Ok(goval::Ok {})); + let ret = goval::Command { + body: Some(goval::command::Body::Ok(goval::Ok {})), + ..Default::default() + }; Ok(Some(ret)) } goval::command::Body::Write(_file) => { // TODO: Store this in the db if &_file.path == ".env" { - let mut ret = goval::Command::default(); - ret.body = Some(goval::command::Body::Ok(goval::Ok {})); + let ret = goval::Command { + body: Some(goval::command::Body::Ok(goval::Ok {})), + ..Default::default() + }; + return Ok(Some(ret)); } @@ -129,9 +141,11 @@ impl traits::Service for GCSFiles { .open(_file.path) .await?; file.set_len(0).await?; - file.write(&_file.content).await?; - let mut ret = goval::Command::default(); - ret.body = Some(goval::command::Body::Ok(goval::Ok {})); + file.write_all(&_file.content).await?; + let ret = goval::Command { + body: Some(goval::command::Body::Ok(goval::Ok {})), + ..Default::default() + }; Ok(Some(ret)) } goval::command::Body::Stat(_) => { diff --git a/services/src/git.rs b/services/src/git.rs index 10bc399..e92fc2b 100644 --- a/services/src/git.rs +++ b/services/src/git.rs @@ -71,26 +71,30 @@ impl traits::Service for Git { match msg { ReplspaceMessage::GithubTokenReq(nonce) => { - let mut token_req = goval::Command::default(); - token_req.body = Some(goval::command::Body::ReplspaceApiGetGitHubToken( - goval::ReplspaceApiGetGitHubToken { - nonce: nonce.clone(), - }, - )); + let token_req = goval::Command { + body: Some(goval::command::Body::ReplspaceApiGetGitHubToken( + goval::ReplspaceApiGetGitHubToken { + nonce: nonce.clone(), + }, + )), + ..Default::default() + }; info.send(token_req, crate::SendSessions::Only(session)) .await?; self.replspace.insert(nonce, respond); } ReplspaceMessage::OpenFileReq(path, wait_for_close, nonce) => { - let mut token_req = goval::Command::default(); - token_req.body = Some(goval::command::Body::ReplspaceApiOpenFile( - goval::ReplspaceApiOpenFile { - nonce: nonce.clone(), - wait_for_close, - file: path, - }, - )); + let token_req = goval::Command { + body: Some(goval::command::Body::ReplspaceApiOpenFile( + goval::ReplspaceApiOpenFile { + nonce: nonce.clone(), + wait_for_close, + file: path, + }, + )), + ..Default::default() + }; info.send(token_req, crate::SendSessions::Only(session)) .await?; diff --git a/services/src/lib.rs b/services/src/lib.rs index ab95e1d..3649c74 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -108,17 +108,15 @@ impl Channel { // Private functions impl Channel { async fn message(&mut self, message: goval::Command, session: i32) -> Result<()> { - match self + if let Some(mut msg) = self ._inner .message(&self.info, message.clone(), session) .await? { - Some(mut msg) => { - msg.r#ref = message.r#ref; - self.info.send(msg, SendSessions::Only(session)).await? - } - None => {} + msg.r#ref = message.r#ref; + self.info.send(msg, SendSessions::Only(session)).await? } + Ok(()) } diff --git a/services/src/ot.rs b/services/src/ot.rs index 7954822..a84bf45 100644 --- a/services/src/ot.rs +++ b/services/src/ot.rs @@ -59,20 +59,19 @@ impl traits::Service for OT { Some(body) => body, }; - if &self.path == "" { + if self.path.is_empty() { if let goval::command::Body::OtLinkFile(link_file) = body.clone() { let path = link_file.file.unwrap().path; - match fs::metadata(path.clone()).await { - Err(_) => { - let mut error = goval::Command::default(); - error.body = Some(goval::command::Body::Error(format!( + if (fs::metadata(path.clone()).await).is_err() { + let error = goval::Command { + body: Some(goval::command::Body::Error(format!( "{}: no such file or directory", path - ))); - return Ok(Some(error)); - } - Ok(_) => {} - }; + ))), + ..Default::default() + }; + return Ok(Some(error)); + } self.path = path.clone(); let byte_contents = fs::read(path.clone()).await?; @@ -111,9 +110,11 @@ impl traits::Service for OT { let mut link_response = goval::Command::default(); - let mut file = goval::File::default(); - file.path = path.clone(); - file.content = byte_contents; + let file = goval::File { + path: path.clone(), + content: byte_contents, + ..Default::default() + }; let _inner = goval::OtLinkFileResponse { version: self.version, @@ -172,10 +173,12 @@ impl traits::Service for OT { goval::ot_op_component::OpComponent::Skip(_skip) => { let skip: usize = _skip.try_into()?; if skip + cursor > self.contents.len_chars() { - let mut err = goval::Command::default(); - err.body = Some(goval::command::Body::Error( - "Invalid skip past bounds".to_string(), - )); + let err = goval::Command { + body: Some(goval::command::Body::Error( + "Invalid skip past bounds".to_string(), + )), + ..Default::default() + }; return Ok(Some(err)); } @@ -184,10 +187,12 @@ impl traits::Service for OT { goval::ot_op_component::OpComponent::Delete(_delete) => { let delete: usize = _delete.try_into()?; if delete + cursor > self.contents.len_chars() { - let mut err = goval::Command::default(); - err.body = Some(goval::command::Body::Error( - "Invalid delete past bounds".to_string(), - )); + let err = goval::Command { + body: Some(goval::command::Body::Error( + "Invalid delete past bounds".to_string(), + )), + ..Default::default() + }; return Ok(Some(err)); } @@ -206,12 +211,10 @@ impl traits::Service for OT { let user_id; if ot.author == goval::ot_packet::Author::Ghostwriter as i32 { user_id = 22261053 // https://replit.com/@ghostwriterai + } else if let Some(user) = info.sessions.get(&session) { + user_id = user.id } else { - if let Some(user) = info.sessions.get(&session) { - user_id = user.id.clone() - } else { - user_id = 23054564 // https://replit.com/@homeval-user - } + user_id = 23054564 // https://replit.com/@homeval-user } let crc32 = crc32fast::hash(to_write.as_bytes()); @@ -238,23 +241,29 @@ impl traits::Service for OT { self.history.push(packet.clone()); - let mut ot_notif = goval::Command::default(); - ot_notif.body = Some(goval::command::Body::Ot(packet)); + let ot_notif = goval::Command { + body: Some(goval::command::Body::Ot(packet)), + ..Default::default() + }; info.send(ot_notif, crate::SendSessions::Everyone).await?; fs::write(&self.path, to_write).await?; - let mut ok = goval::Command::default(); - ok.body = Some(goval::command::Body::Ok(goval::Ok {})); + let ok = goval::Command { + body: Some(goval::command::Body::Ok(goval::Ok {})), + ..Default::default() + }; + Ok(Some(ok)) } goval::command::Body::OtNewCursor(cursor) => { self.cursors.insert(cursor.id.clone(), cursor.clone()); - let mut cursor_notif = goval::Command::default(); - - cursor_notif.body = Some(goval::command::Body::OtNewCursor(cursor)); + let cursor_notif = goval::Command { + body: Some(goval::command::Body::OtNewCursor(cursor)), + ..Default::default() + }; info.send(cursor_notif, crate::SendSessions::EveryoneExcept(session)) .await?; @@ -263,9 +272,10 @@ impl traits::Service for OT { goval::command::Body::OtDeleteCursor(cursor) => { self.cursors.remove(&cursor.id); - let mut cursor_delete_notif = goval::Command::default(); - - cursor_delete_notif.body = Some(goval::command::Body::OtDeleteCursor(cursor)); + let cursor_delete_notif = goval::Command { + body: Some(goval::command::Body::OtDeleteCursor(cursor)), + ..Default::default() + }; info.send( cursor_delete_notif, @@ -292,8 +302,10 @@ impl traits::Service for OT { Ok(Some(history_result)) } goval::command::Body::Flush(_) => { - let mut ok = goval::Command::default(); - ok.body = Some(goval::command::Body::Ok(goval::Ok {})); + let ok = goval::Command { + body: Some(goval::command::Body::Ok(goval::Ok {})), + ..Default::default() + }; Ok(Some(ok)) } _ => { @@ -347,8 +359,10 @@ impl traits::Service for OT { self.history.push(packet.clone()); - let mut ot_notif = goval::Command::default(); - ot_notif.body = Some(goval::command::Body::Ot(packet)); + let ot_notif = goval::Command { + body: Some(goval::command::Body::Ot(packet)), + ..Default::default() + }; info.send(ot_notif, crate::SendSessions::Everyone).await?; } @@ -372,15 +386,19 @@ impl traits::Service for OT { _session: i32, _sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { - if &self.path == "" { - let mut cmd = goval::Command::default(); - cmd.body = Some(goval::command::Body::Otstatus(goval::OtStatus::default())); + if self.path.is_empty() { + let cmd = goval::Command { + body: Some(goval::command::Body::Otstatus(goval::OtStatus::default())), + ..Default::default() + }; return Ok(Some(cmd)); } let mut status = goval::Command::default(); - let mut file = goval::File::default(); - file.path = self.path.clone(); + let file = goval::File { + path: self.path.clone(), + ..Default::default() + }; let mut cursors = vec![]; diff --git a/services/src/output.rs b/services/src/output.rs index 140eb77..157dcab 100644 --- a/services/src/output.rs +++ b/services/src/output.rs @@ -47,12 +47,11 @@ impl traits::Service for Output { } let mut status = goval::Command::default(); - let state; - if self.start_time.is_some() { - state = goval::State::Running + let state = if self.start_time.is_some() { + goval::State::Running } else { - state = goval::State::Stopped - } + goval::State::Stopped + }; status.body = Some(goval::command::Body::State(state.into())); Ok(Some(status)) @@ -118,9 +117,11 @@ impl traits::Service for Output { new_frame.body = Some(goval::command::Body::OutputBlockStartEvent(event)); info.send(new_frame, crate::SendSessions::Everyone).await?; - let mut status = goval::Command::default(); + let status = goval::Command { + body: Some(goval::command::Body::State(goval::State::Running.into())), + ..Default::default() + }; - status.body = Some(goval::command::Body::State(goval::State::Running.into())); info.send(status, crate::SendSessions::Everyone).await?; } goval::command::Body::Clear(_) => { @@ -168,15 +169,20 @@ impl traits::Service for Output { info.send(end_frame, crate::SendSessions::Everyone).await?; if exit_code != 0 { - let mut error = goval::Command::default(); - error.body = Some(goval::command::Body::Error(format!( - "exit code {exit_code}" - ))); + let error = goval::Command { + body: Some(goval::command::Body::Error(format!( + "exit code {exit_code}" + ))), + ..Default::default() + }; + info.send(error, crate::SendSessions::Everyone).await?; } - let mut status = goval::Command::default(); - status.body = Some(goval::command::Body::State(goval::State::Stopped.into())); + let status = goval::Command { + body: Some(goval::command::Body::State(goval::State::Stopped.into())), + ..Default::default() + }; info.send(status, crate::SendSessions::Everyone).await?; Ok(()) } diff --git a/services/src/presence.rs b/services/src/presence.rs index 4d30416..a912fc6 100644 --- a/services/src/presence.rs +++ b/services/src/presence.rs @@ -41,23 +41,24 @@ impl traits::Service for Presence { match body { goval::command::Body::FollowUser(follow) => { - let mut follow_notif = goval::Command::default(); - - follow_notif.body = Some(goval::command::Body::FollowUser(goval::FollowUser { - session, - })); + let follow_notif = goval::Command { + body: Some(goval::command::Body::FollowUser(goval::FollowUser { + session, + })), + ..Default::default() + }; info.send(follow_notif, SendSessions::Only(follow.session)) .await?; Ok(None) } goval::command::Body::UnfollowUser(unfollow) => { - let mut unfollow_notif = goval::Command::default(); - - unfollow_notif.body = - Some(goval::command::Body::UnfollowUser(goval::UnfollowUser { + let unfollow_notif = goval::Command { + body: Some(goval::command::Body::UnfollowUser(goval::UnfollowUser { session, - })); + })), + ..Default::default() + }; info.send(unfollow_notif, SendSessions::Only(unfollow.session)) .await?; @@ -117,13 +118,17 @@ impl traits::Service for Presence { _inner.user = self.users.clone(); roster.body = Some(goval::command::Body::Roster(_inner)); - let mut user = goval::User::default(); - user.session = session; - user.id = client.id; - user.name = client.username; + let user = goval::User { + session, + id: client.id, + name: client.username, + ..Default::default() + }; - let mut join = goval::Command::default(); - join.body = Some(goval::command::Body::Join(user.clone())); + let join = goval::Command { + body: Some(goval::command::Body::Join(user.clone())), + ..Default::default() + }; info.send(join, SendSessions::EveryoneExcept(session)) .await?; diff --git a/services/src/shell.rs b/services/src/shell.rs index d81dad0..d924dd0 100644 --- a/services/src/shell.rs +++ b/services/src/shell.rs @@ -66,22 +66,22 @@ impl traits::Service for Shell { } #[cfg(target_family = "unix")] -static DEFAULT_SHELL: &'static str = "sh"; +static DEFAULT_SHELL: &str = "sh"; #[cfg(target_family = "windows")] -static DEFAULT_SHELL: &'static str = "pwsh"; +static DEFAULT_SHELL: &str = "pwsh"; impl Shell { async fn start_pty(info: &super::types::ChannelInfo) -> Result { let mut env = HashMap::new(); env.insert("REPLIT_GIT_TOOLS_CHANNEL_FROM".into(), info.id.to_string()); - Ok(Pty::start( + Pty::start( vec![std::env::var("SHELL").unwrap_or(DEFAULT_SHELL.to_string())], info.id, Arc::new(RwLock::new(info.clients.clone())), info.sender.clone(), Some(env), ) - .await?) + .await } pub async fn new(info: &super::types::ChannelInfo) -> Result { Ok(Shell { diff --git a/services/src/snapshot.rs b/services/src/snapshot.rs index 0806a21..7def841 100644 --- a/services/src/snapshot.rs +++ b/services/src/snapshot.rs @@ -19,8 +19,10 @@ impl traits::Service for Snapshot { match body { goval::command::Body::FsSnapshot(_) => { - let mut ok = goval::Command::default(); - ok.body = Some(goval::command::Body::Ok(goval::Ok {})); + let ok = goval::Command { + body: Some(goval::command::Body::Ok(goval::Ok {})), + ..Default::default() + }; Ok(Some(ok)) } _ => Ok(None), diff --git a/services/src/toolchain.rs b/services/src/toolchain.rs index a5559f6..153e992 100644 --- a/services/src/toolchain.rs +++ b/services/src/toolchain.rs @@ -19,11 +19,12 @@ impl traits::Service for Toolchain { }; match body { goval::command::Body::NixModulesGetRequest(_) => { - let mut modules = goval::Command::default(); - - modules.body = Some(goval::command::Body::NixModulesGetResponse( - goval::NixModulesGetResponse::default(), - )); + let modules = goval::Command { + body: Some(goval::command::Body::NixModulesGetResponse( + goval::NixModulesGetResponse::default(), + )), + ..Default::default() + }; Ok(Some(modules)) } @@ -31,16 +32,20 @@ impl traits::Service for Toolchain { let mut toolchain = goval::Command::default(); let mut inner = goval::ToolchainGetResponse::default(); - let mut configs = goval::ToolchainConfigs::default(); - configs.runs = vec![goval::RunOption { - id: "homeval/test".into(), - name: "Test".into(), - file_param: false, - language: "idk".into(), - file_type_attrs: None, - interpreter: false, - optional_file_param: false, - }]; + + let configs = goval::ToolchainConfigs { + runs: vec![goval::RunOption { + id: "homeval/test".into(), + name: "Test".into(), + file_param: false, + language: "idk".into(), + file_type_attrs: None, + interpreter: false, + optional_file_param: false, + }], + ..Default::default() + }; + inner.configs = Some(configs); toolchain.body = Some(goval::command::Body::ToolchainGetResponse(inner)); diff --git a/services/src/types/channel_info.rs b/services/src/types/channel_info.rs index 9de3793..02372ed 100644 --- a/services/src/types/channel_info.rs +++ b/services/src/types/channel_info.rs @@ -36,7 +36,7 @@ impl ChannelInfo { message.session = 0; let mut _clients = vec![]; for client in self.clients.keys() { - _clients.push(client.clone()) + _clients.push(*client) } clients = _clients; @@ -46,7 +46,7 @@ impl ChannelInfo { let mut _clients = vec![]; for client in self.clients.keys() { if client != &excluded { - _clients.push(client.clone()) + _clients.push(*client) } } diff --git a/services/src/types/config.rs b/services/src/types/config.rs index 2e72a81..dfa7b2d 100644 --- a/services/src/types/config.rs +++ b/services/src/types/config.rs @@ -147,25 +147,25 @@ pub mod dotreplit { pub hidden: Option>, } - impl Into for DotReplit { - fn into(self) -> goval::DotReplit { + impl From for goval::DotReplit { + fn from(val: DotReplit) -> Self { let mut ret = goval::DotReplit::default(); - if let Some(run) = self.run { + if let Some(run) = val.run { // let mut inner = goval::Exec::default(); // inner.args = vec!["sh".into(), "-c".into(), run]; ret.run = Some(run.into()); } - if let Some(lang) = self.language { + if let Some(lang) = val.language { ret.language = lang; } - if let Some(entrypoint) = self.entrypoint { + if let Some(entrypoint) = val.entrypoint { ret.entrypoint = entrypoint; } - if let Some(languages) = self.languages { + if let Some(languages) = val.languages { let mut inner = HashMap::new(); for (lang, data) in languages.iter() { @@ -175,7 +175,7 @@ pub mod dotreplit { ret.languages = inner } - if let Some(hidden) = self.hidden { + if let Some(hidden) = val.hidden { ret.hidden = hidden; } @@ -198,19 +198,19 @@ pub mod dotreplit { pub language_server: Option, } - impl Into for DotReplitLanguage { - fn into(self) -> goval::DotReplitLanguage { + impl From for goval::DotReplitLanguage { + fn from(val: DotReplitLanguage) -> Self { let mut ret = goval::DotReplitLanguage::default(); - if let Some(pattern) = self.pattern { + if let Some(pattern) = val.pattern { ret.pattern = pattern; } - if let Some(syntax) = self.syntax { + if let Some(syntax) = val.syntax { ret.syntax = syntax; } - if let Some(language_server) = self.language_server { + if let Some(language_server) = val.language_server { ret.language_server = Some(language_server.into()); } @@ -236,22 +236,22 @@ pub struct LanguageServerConfig { pub initialization_options_json: Option, } -impl Into for LanguageServerConfig { - fn into(self) -> goval::LanguageServerConfig { +impl From for goval::LanguageServerConfig { + fn from(val: LanguageServerConfig) -> Self { let mut ret = goval::LanguageServerConfig::default(); - if let Some(start_command) = self.start_command { + if let Some(start_command) = val.start_command { // let mut inner = goval::Exec::default(); // inner.args = vec!["sh".into(), "-c".into(), start_command]; // ret.start_command = Some(inner); ret.start_command = Some(start_command.into()); } - if let Some(configuration_json) = self.configuration_json { + if let Some(configuration_json) = val.configuration_json { ret.configuration_json = configuration_json; } - if let Some(initialization_options_json) = self.initialization_options_json { + if let Some(initialization_options_json) = val.initialization_options_json { ret.initialization_options_json = initialization_options_json; }; @@ -293,31 +293,31 @@ pub struct Exec { pub split_logs: Option, } -impl Into for Exec { - fn into(self) -> goval::Exec { +impl From for goval::Exec { + fn from(val: Exec) -> Self { let mut ret = goval::Exec::default(); - if let Some(args) = self.args { + if let Some(args) = val.args { ret.args = args; } - if let Some(env) = self.env { + if let Some(env) = val.env { ret.env = env; } - if let Some(blocking) = self.blocking { + if let Some(blocking) = val.blocking { ret.blocking = blocking; } - if let Some(split_stderr) = self.split_stderr { + if let Some(split_stderr) = val.split_stderr { ret.split_stderr = split_stderr; } - if let Some(split_logs) = self.split_logs { + if let Some(split_logs) = val.split_logs { ret.split_logs = split_logs; } - if let Some(lifecycle) = self.lifecycle { + if let Some(lifecycle) = val.lifecycle { ret.lifecycle = match lifecycle { ExecLifecycle::NonBlocking => goval::exec::Lifecycle::NonBlocking, ExecLifecycle::Blocking => goval::exec::Lifecycle::Blocking, diff --git a/services/src/types/pty.rs b/services/src/types/pty.rs index 1a7101e..019a439 100644 --- a/services/src/types/pty.rs +++ b/services/src/types/pty.rs @@ -33,15 +33,14 @@ static MAX_SCROLLBACK: usize = 10_000; impl Write for PtyWriter { fn write(&mut self, buf: &[u8]) -> std::io::Result { let mut cmd = goval::Command::default(); - let output: String; - match String::from_utf8(buf.to_vec()) { - Ok(str) => output = str, + let output = match String::from_utf8(buf.to_vec()) { + Ok(str) => str, Err(err) => { error!("Invalid utf-8 output in pty handler"); return Err(Error::new(ErrorKind::Other, err.utf8_error())); } - } + }; cmd.body = Some(goval::command::Body::Output(output.clone())); cmd.channel = self.channel; @@ -265,7 +264,7 @@ impl Pty { return Err(format_err!("Can't write to a cancelled pty")); } - self.writer.write(task.as_bytes())?; + self.writer.write_all(task.as_bytes())?; Ok(()) } @@ -277,13 +276,15 @@ impl Pty { if self.cancelled.load(std::sync::atomic::Ordering::SeqCst) { return Err(format_err!("Can't add a session to a cancelled pty")); }; - let mut cmd = goval::Command::default(); - cmd.body = Some(goval::command::Body::Output( - self.scrollback.read().await.clone(), - )); - cmd.session = session; - cmd.channel = self.channel; + let cmd = goval::Command { + body: Some(goval::command::Body::Output( + self.scrollback.read().await.clone(), + )), + session, + channel: self.channel, + ..Default::default() + }; sender.send(IPCMessage { command: cmd, diff --git a/src/goval_server.rs b/src/goval_server.rs index 2c52b09..a5b2296 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -75,7 +75,7 @@ async fn on_wsv2_upgrade(socket: WebSocket, token: String, state: AppState, addr debug!("Mutex acquired..."); *max_session += 1; - let session_id = max_session.clone(); + let session_id = *max_session; drop(max_session); let (send_to_session, session_recv) = mpsc::unbounded_channel::(); @@ -120,23 +120,23 @@ async fn handle_message( ) { let cmd: Command = message.clone().command; - let cmd_body: goval::command::Body; - - match cmd.body { + let cmd_body = match cmd.body { None => { error!(command = as_debug!(cmd); "MISSING COMMAND BODY"); return; } - Some(body) => cmd_body = body, - } + Some(body) => body, + }; if cmd.channel == 0 { match cmd_body { goval::command::Body::Ping(_) => { - let mut pong = goval::Command::default(); - pong.body = Some(goval::command::Body::Pong(goval::Pong::default())); - pong.r#ref = cmd.r#ref; - pong.channel = 0; + let pong = goval::Command { + body: Some(goval::command::Body::Pong(goval::Pong::default())), + r#ref: cmd.r#ref, + channel: 0, + ..Default::default() + }; if let Some(sender) = session_map.read().await.get(&message.session) { match sender.send(message.replace_cmd(pong)) { @@ -174,7 +174,7 @@ async fn handle_message( if let goval::command::Body::Input(input) = cmd_body { if let Some(pty_id) = PROCCESS_CHANNEL_TO_ID.read().await.get(&cmd.channel) { let mut to_continue = false; - if let Some(queue) = crate::PROCCESS_WRITE_MESSAGES.read().await.get(&pty_id) { + if let Some(queue) = crate::PROCCESS_WRITE_MESSAGES.read().await.get(pty_id) { queue.push(input); to_continue = true; } else { @@ -232,7 +232,7 @@ async fn open_channel( && channel.service.clone() == open_chan.service { found = true; - channel_id_held = id.clone(); + channel_id_held = *id; continue; } } @@ -243,17 +243,15 @@ async fn open_channel( let service = open_chan.service.clone(); let mut max_channel = max_channel.lock().await; *max_channel += 1; - let channel_id = max_channel.clone(); - channel_id_held = channel_id.clone(); + let channel_id = *max_channel; + channel_id_held = channel_id; drop(max_channel); - let _channel_name: Option; - - if open_chan.name.len() > 0 { - _channel_name = Some(open_chan.name); + let _channel_name = if !open_chan.name.is_empty() { + Some(open_chan.name) } else { - _channel_name = None; - } + None + }; let service_data = ServiceMetadata { service: service.clone(), @@ -293,8 +291,9 @@ async fn open_channel( if !found { error!("Couldnt make channel"); let mut protocol_error = goval::Command::default(); - let mut _inner = goval::ProtocolError::default(); - _inner.text = "Could not create / attach channel".to_string(); + let _inner = goval::ProtocolError { + text: "Could not create / attach channel".to_string(), + }; protocol_error.body = Some(goval::command::Body::ProtocolError(_inner)); protocol_error.r#ref = message.command.r#ref.clone(); @@ -311,9 +310,12 @@ async fn open_channel( } let mut open_chan_res = goval::Command::default(); - let mut _open_res = goval::OpenChannelRes::default(); - _open_res.state = goval::open_channel_res::State::Created.into(); - _open_res.id = channel_id_held; + let _open_res = goval::OpenChannelRes { + state: goval::open_channel_res::State::Created.into(), + id: channel_id_held, + ..Default::default() + }; + open_chan_res.body = Some(goval::command::Body::OpenChanRes(_open_res)); open_chan_res.r#ref = message.command.r#ref.clone(); open_chan_res.channel = 0; @@ -382,7 +384,7 @@ async fn detach_channel(channel: i32, session: i32, forced: bool) -> Result<()> .write() .await .entry(session) - .and_modify(|channels| channels.retain(|chan: &i32| chan.clone() != channel)); + .and_modify(|channels| channels.retain(|chan: &i32| *chan != channel)); let msg_lock = CHANNEL_MESSAGES.read().await; @@ -398,8 +400,8 @@ async fn detach_channel(channel: i32, session: i32, forced: bool) -> Result<()> match guard.get_mut(&channel) { Some(arr) => { - arr.retain(|sess| sess.clone() != session); - if arr.len() == 0 { + arr.retain(|sess| *sess != session); + if arr.is_empty() { trace!(channel = channel; "Shutting down channel"); queue.send(ChannelMessage::Shutdown)?; @@ -427,8 +429,7 @@ async fn send_message( message: goval::Command, stream: &mut futures_util::stream::SplitSink, ) -> Result<()> { - let mut buf = Vec::new(); - buf.reserve(message.encoded_len()); + let mut buf = Vec::with_capacity(message.encoded_len()); message.encode(&mut buf)?; Ok(stream.send(WsMessage::Binary(buf)).await?) @@ -454,24 +455,28 @@ async fn accept_connection( let (mut write, mut read) = ws_stream.split(); let mut boot_status = goval::Command::default(); - let mut inner = goval::BootStatus::default(); - inner.stage = goval::boot_status::Stage::Complete.into(); + let inner = goval::BootStatus { + stage: goval::boot_status::Stage::Complete.into(), + ..Default::default() + }; boot_status.body = Some(goval::command::Body::BootStatus(inner)); send_message(boot_status, &mut write).await?; // Sending container state let mut container_state = goval::Command::default(); - let mut inner_state = goval::ContainerState::default(); - inner_state.state = goval::container_state::State::Ready.into(); + let inner_state = goval::ContainerState { + state: goval::container_state::State::Ready.into(), + }; container_state.body = Some(goval::command::Body::ContainerState(inner_state)); send_message(container_state, &mut write).await?; // Sending server info message let mut toast = goval::Command::default(); - let mut inner_state = goval::Toast::default(); - inner_state.text = format!("Hello @{}, welcome to homeval!", client.username); + let inner_state = goval::Toast { + text: format!("Hello @{}, welcome to homeval!", client.username), + }; toast.body = Some(goval::command::Body::Toast(inner_state)); send_message(toast, &mut write).await?; @@ -495,17 +500,16 @@ async fn accept_connection( Ok(msg) => match msg { WsMessage::Binary(buf) => { let _message: anyhow::Result = buf.try_into(); - let message: IPCMessage; - match _message { + let message = match _message { Ok(mut msg) => { msg.session = session; - message = msg + msg } Err(err) => { error!(error = as_display!(err), session = session; "Error decoding message from client"); continue; } - } + }; if let Err(err) = propagate.send(message) { error!(session = session, error = as_error!(err); "An error occured when enqueing message to global message queue") @@ -515,7 +519,7 @@ async fn accept_connection( warn!(session = session; "CLOSING SESSION"); for _channel in SESSION_CHANNELS.read().await.get(&session).unwrap().iter() { - let channel = _channel.clone(); + let channel = *_channel; tokio::spawn(async move { match detach_channel(channel, session, true).await { Ok(_) => {} diff --git a/src/main.rs b/src/main.rs index a7c8cdb..8723d24 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,7 +29,7 @@ pub static START_TIME: LazyLock = LazyLock::new(Instant::now); static CPU_STATS: LazyLock> = LazyLock::new(|| Arc::new(cpu_time::ProcessTime::now())); -pub static IMPLEMENTED_SERVICES: LazyLock> = LazyLock::new(|| vec![]); +pub static IMPLEMENTED_SERVICES: LazyLock> = LazyLock::new(Vec::new); pub static DOTREPLIT_CONFIG: LazyLock>> = LazyLock::new(|| { Arc::new(RwLock::const_new( @@ -89,7 +89,7 @@ async fn main() -> Result<(), Error> { std::env::set_var("HOMEVAL_START_DIR", std::env::current_dir()?); // console_subscriber::init(); - let _ = env_logger::try_init().unwrap(); + env_logger::try_init().unwrap(); #[cfg(feature = "database")] database::setup().await.unwrap(); diff --git a/src/parse_paseto.rs b/src/parse_paseto.rs index 6accb46..d96f1c4 100644 --- a/src/parse_paseto.rs +++ b/src/parse_paseto.rs @@ -1,6 +1,5 @@ use anyhow::Result; use base64::{engine::general_purpose, Engine as _}; -use goval; use homeval_services::ClientInfo; use prost::Message; use std::io::Error; @@ -16,7 +15,7 @@ static KEYS: tokio::sync::OnceCell> = use log::{as_display, warn}; fn parse_noverify(token: &str) -> Result<(Vec, bool)> { - let token_parts = token.split(".").collect::>(); + let token_parts = token.split('.').collect::>(); if token_parts.len() < 3 { return Err(Error::new(std::io::ErrorKind::InvalidData, "Invalid Token").into()); } diff --git a/src/replspace_server.rs b/src/replspace_server.rs index 0fb55f9..37b96ef 100644 --- a/src/replspace_server.rs +++ b/src/replspace_server.rs @@ -48,7 +48,7 @@ async fn get_gh_token(_query: Option>) -> (StatusCode, Jso debug!(channel = query.channel; "Got git askpass"); let last_session = crate::LAST_SESSION_USING_CHANNEL.read().await; - session = last_session.get(&query.channel).unwrap_or(&0).clone(); + session = *last_session.get(&query.channel).unwrap_or(&0); } else { debug!("Got git askpass without channel id"); session = 0; @@ -68,11 +68,10 @@ async fn get_gh_token(_query: Option>) -> (StatusCode, Jso drop(msg_lock); - let res; let msg = rx.recv().await; rx.close(); - match msg { - Some(token) => res = token, + let res = match msg { + Some(token) => token, None => { error!("rx#recv() returned None in gh get token"); return ( @@ -83,12 +82,10 @@ async fn get_gh_token(_query: Option>) -> (StatusCode, Jso }), ); } - } - - let token; + }; - match res { - ReplspaceMessage::GithubTokenRes(_token) => token = _token, + let token = match res { + ReplspaceMessage::GithubTokenRes(token) => token, _ => { error!( result = as_debug!(res); @@ -102,7 +99,7 @@ async fn get_gh_token(_query: Option>) -> (StatusCode, Jso }), ); } - } + }; ( StatusCode::OK, @@ -135,7 +132,7 @@ async fn open_file(Json(query): Json) -> (StatusCode, Json) -> (StatusCode, Json { - res = token; - } + let res = match msg { + Some(token) => token, None => { error!("rx#none() returned none in replspace api open file fetcher"); return ( @@ -199,7 +193,7 @@ async fn open_file(Json(query): Json) -> (StatusCode, Json ( @@ -213,12 +207,12 @@ async fn open_file(Json(query): Json) -> (StatusCode, Json Date: Sat, 13 Jan 2024 17:11:44 -0800 Subject: [PATCH 026/103] feat: update and add a lot of stuff lol --- .gitignore | 4 +- Cargo.toml | 11 +- services/src/exec.rs | 137 +++++++++++++++++++++ services/src/lib.rs | 8 +- services/src/types/channel_info.rs | 1 + services/src/types/messaging.rs | 6 +- services/src/types/mod.rs | 5 + services/src/types/proc.rs | 191 +++++++++++++++++++++++++++++ src/database.rs | 8 +- src/main.rs | 4 +- src/parse_paseto.rs | 60 ++++----- src/repldb_server.rs | 9 +- 12 files changed, 396 insertions(+), 48 deletions(-) create mode 100644 services/src/exec.rs create mode 100644 services/src/types/proc.rs diff --git a/.gitignore b/.gitignore index ac32280..e487337 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,6 @@ site flamegraph.svg perf.data -perf.data.old \ No newline at end of file +perf.data.old + +data \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 3178e0f..d72ab67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,8 @@ +cargo-features = ["codegen-backend"] + +[profile.dev] +codegen-backend = "cranelift" + [package] name = "homeval" version = "0.3.0" @@ -12,12 +17,12 @@ See https://govaldocs.pages.dev""" members = [".", "migration", "entity", "services", "protobuf"] [features] -default = ["replspace"] # "database", "repldb", "verify_connections"] +default = ["replspace", "database", "repldb", "verify_connections"] repldb = ["database"] database = ["dep:sea-orm", "dep:sea-query", "dep:migration", "dep:entity"] replspace = [] fun-stuff = ["dep:chrono", "dep:chrono-tz"] -verify_connections = ["dep:pasetors", "dep:hyper", "dep:hyper-tls"] +verify_connections = ["dep:hyper", "dep:hyper-tls"] [dependencies] goval = { path = "protobuf", package = "protobuf" } @@ -48,7 +53,7 @@ sea-orm = { version = "0.11.3", features = [ "sqlx-postgres", "runtime-tokio-rus migration = { path = "migration", optional = true} entity = { path = "entity", optional = true} sea-query = { version = "0.28.5", optional = true } -pasetors = { version = "0.6.7", default-features = false, features = ["v2"], optional = true } +pasetors = { version = "0.6.7", default-features = false, features = ["v2"] } hyper = { version = "0.14.26", features = ["http1", "http2", "client"], optional = true } hyper-tls = { version = "0.5.0", optional = true } anyhow = "1.0.71" diff --git a/services/src/exec.rs b/services/src/exec.rs new file mode 100644 index 0000000..56d9902 --- /dev/null +++ b/services/src/exec.rs @@ -0,0 +1,137 @@ +pub struct Exec { + running: bool, + queue: Vec<(goval::Exec, String)>, + current_ref: String, +} + +use std::collections::HashMap; + +use crate::Proc; + +use super::traits; +use anyhow::{format_err, Result}; +use async_trait::async_trait; + +#[async_trait] +impl traits::Service for Exec { + async fn message( + &mut self, + info: &super::types::ChannelInfo, + message: goval::Command, + _session: i32, + ) -> Result> { + let body = match message.body.clone() { + None => return Err(format_err!("Expected command body")), + Some(body) => body, + }; + + if let goval::command::Body::Exec(exec) = body { + if self.running { + if !(exec.blocking || exec.lifecycle == goval::exec::Lifecycle::Blocking as i32) { + info.send( + goval::Command { + body: Some(goval::command::Body::Error("Already running".to_string())), + ..Default::default() + }, + crate::SendSessions::Everyone, + ) + .await?; + return Ok(None); + } + + self.queue.push((exec, message.r#ref)); + } else { + info.send( + goval::Command { + body: Some(goval::command::Body::State(goval::State::Stopped.into())), + ..Default::default() + }, + crate::SendSessions::Everyone, + ) + .await?; + self.running = true; + self.current_ref = message.r#ref; + Proc::new(exec.args, info.id, info.sender.clone(), Some(exec.env)).await?; + info.send( + goval::Command { + body: Some(goval::command::Body::State(goval::State::Running.into())), + ..Default::default() + }, + crate::SendSessions::Everyone, + ) + .await?; + } + } + + Ok(None) + } + + async fn proccess_died( + &mut self, + info: &super::types::ChannelInfo, + exit_code: i32, + ) -> Result<()> { + self.running = false; + if exit_code == 0 { + info.send( + goval::Command { + body: Some(goval::command::Body::Ok(goval::Ok {})), + r#ref: self.current_ref.clone(), + ..Default::default() + }, + crate::SendSessions::Everyone, + ) + .await?; + } else { + info.send( + goval::Command { + body: Some(goval::command::Body::Error(format!( + "exit status {exit_code}" + ))), + r#ref: self.current_ref.clone(), + ..Default::default() + }, + crate::SendSessions::Everyone, + ) + .await?; + } + + self.current_ref = String::new(); + + info.send( + goval::Command { + body: Some(goval::command::Body::State(goval::State::Stopped.into())), + ..Default::default() + }, + crate::SendSessions::Everyone, + ) + .await?; + + if !self.queue.is_empty() { + self.running = true; + let item = self.queue.swap_remove(0); + Proc::new(item.0.args, info.id, info.sender.clone(), Some(item.0.env)).await?; + self.current_ref = item.1; + info.send( + goval::Command { + body: Some(goval::command::Body::State(goval::State::Running.into())), + ..Default::default() + }, + crate::SendSessions::Everyone, + ) + .await?; + } + + Ok(()) + } +} + +impl Exec { + pub fn new() -> Self { + Exec { + running: false, + queue: vec![], + current_ref: String::new(), + } + } +} diff --git a/services/src/lib.rs b/services/src/lib.rs index 3649c74..7876bd0 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -1,5 +1,6 @@ mod chat; mod dotreplit; +mod exec; mod gcsfiles; mod git; mod ot; @@ -19,7 +20,6 @@ use log::error; use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; -use types::config::dotreplit::DotReplit; pub use types::*; pub struct Channel { @@ -56,6 +56,7 @@ impl Channel { "shell" => Box::new(shell::Shell::new(&info).await?), "toolchain" => Box::new(toolchain::Toolchain {}), "git" => Box::new(git::Git::new()), + "exec" => Box::new(exec::Exec::new()), "dotreplit" => Box::new(dotreplit::DotReplit {}), "null" => Box::new(stub::Stub {}), // This channel never does anything "open" => Box::new(stub::Stub {}), // Stub until infra is set up to handle this @@ -79,7 +80,6 @@ impl Channel { ChannelMessage::ProcessDead(exit_code) => { self._inner.proccess_died(&self.info, exit_code).await } - ChannelMessage::CmdDead(_) => todo!(), ChannelMessage::Replspace(session, msg, respond) => { self._inner .replspace(&self.info, msg, session, respond) @@ -93,6 +93,9 @@ impl Channel { } }, ChannelMessage::FSEvent(event) => self._inner.fsevent(&self.info, event).await, + ChannelMessage::ExternalMessage(msg, sessions) => { + self.info.send(msg, sessions).await + } }; match result { @@ -162,4 +165,5 @@ pub static IMPLEMENTED_SERVICES: &[&str] = &[ "shell", "toolchain", "dotreplit", + "exec", ]; diff --git a/services/src/types/channel_info.rs b/services/src/types/channel_info.rs index 02372ed..d699e64 100644 --- a/services/src/types/channel_info.rs +++ b/services/src/types/channel_info.rs @@ -11,6 +11,7 @@ use crate::config::dotreplit::DotReplit; use super::client::ClientInfo; use super::messaging::IPCMessage; +#[derive(Clone, Copy, Debug)] pub enum SendSessions { Only(i32), EveryoneExcept(i32), diff --git a/services/src/types/messaging.rs b/services/src/types/messaging.rs index 2fede0f..e8c1502 100644 --- a/services/src/types/messaging.rs +++ b/services/src/types/messaging.rs @@ -5,6 +5,8 @@ use serde; use serde::{Deserialize, Serialize}; use tokio::sync::mpsc::Sender; +use crate::SendSessions; + use super::client::ClientInfo; #[derive(Serialize, Deserialize, Debug, Clone)] @@ -28,10 +30,10 @@ pub enum ChannelMessage { ), Detach(i32), ProcessDead(i32), - CmdDead(i32), FSEvent(super::FSEvent), Replspace(i32, ReplspaceMessage, Option>), // session, message - Shutdown, // Shutdown the service, value has to be true so that runtime.js can match it in an if check + Shutdown, + ExternalMessage(goval::Command, SendSessions), } #[derive(Debug, Clone)] diff --git a/services/src/types/mod.rs b/services/src/types/mod.rs index 7be0526..b3ecc3d 100644 --- a/services/src/types/mod.rs +++ b/services/src/types/mod.rs @@ -14,5 +14,10 @@ pub mod service; pub use service::ServiceMetadata; pub mod pty; +pub use pty::Pty; pub mod config; +pub use config::dotreplit::DotReplit; + +pub mod proc; +pub use proc::Proc; diff --git a/services/src/types/proc.rs b/services/src/types/proc.rs new file mode 100644 index 0000000..e7c36aa --- /dev/null +++ b/services/src/types/proc.rs @@ -0,0 +1,191 @@ +use std::{ + collections::{HashMap, VecDeque}, + pin::Pin, + process::{ExitStatus, Stdio}, + sync::{atomic::AtomicBool, Arc}, + task::{Context, Poll}, +}; + +use crate::{ChannelMessage, IPCMessage, SendSessions}; +use anyhow::Result; +use log::{error, trace}; +use tokio::{ + io::{AsyncReadExt, AsyncWrite, AsyncWriteExt, ReadBuf}, + process::ChildStdin, + sync::RwLock, +}; + +struct CmdWriter { + channel: i32, + contact: tokio::sync::mpsc::UnboundedSender, + cancelled: Arc, + error: bool, +} + +impl AsyncWrite for CmdWriter { + fn poll_write( + self: Pin<&mut Self>, + _cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + if self.cancelled.load(std::sync::atomic::Ordering::SeqCst) { + return Poll::Ready(Err(std::io::Error::new( + std::io::ErrorKind::Other, + "cancelled", + ))); + } + let mut cmd = goval::Command::default(); + let output = match String::from_utf8(buf.to_vec()) { + Ok(str) => str, + Err(err) => { + error!("Invalid utf-8 output in pty handler"); + + return Poll::Ready(Err(std::io::Error::new( + std::io::ErrorKind::Other, + err.utf8_error(), + ))); + } + }; + + if self.error { + cmd.body = Some(goval::command::Body::Error(output)); + } else { + cmd.body = Some(goval::command::Body::Output(output)); + } + + cmd.channel = self.channel; + if self + .contact + .send(ChannelMessage::ExternalMessage(cmd, SendSessions::Everyone)) + .is_err() + { + return Poll::Ready(Err(std::io::Error::new( + std::io::ErrorKind::Other, + "Proc recv'ing channel was dropped", + ))); + } + Poll::Ready(Ok(buf.len())) + } + + fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn poll_shutdown( + self: Pin<&mut Self>, + _: &mut Context<'_>, + ) -> Poll> { + Poll::Ready(Ok(())) + } +} + +pub struct Proc { + channel: i32, + cancelled: Arc, + contact: tokio::sync::mpsc::UnboundedSender, + stdin: ChildStdin, +} + +impl Proc { + pub async fn new( + _args: Vec, + channel: i32, + contact: tokio::sync::mpsc::UnboundedSender, + _env: Option>, + ) -> Result { + let cancelled = Arc::new(AtomicBool::new(false)); + + let mut cmd = tokio::process::Command::new(&_args[0]); + let args = &mut VecDeque::from(_args.to_vec()); + trace!("{:#?}", args); + VecDeque::pop_front(args); + for arg in args { + cmd.arg(arg); + } + // debug!("{:#?}", std::env::current_dir()?); + cmd.current_dir(std::env::current_dir()?); + cmd.stdout(Stdio::piped()); + cmd.stderr(Stdio::piped()); + cmd.stdin(Stdio::piped()); + let mut child = cmd.spawn()?; + let mut stdout_opt = child.stdout.take().expect("TODO: handle this"); + let mut stderr_opt = child.stderr.take().expect("TODO: handle this"); + let stdin = child.stdin.take().expect("TODO: handle this"); + + let contact_clone = contact.clone(); + let cancelled_clone = cancelled.clone(); + tokio::task::spawn(async move { + let mut sender = CmdWriter { + channel, + contact: contact_clone, + cancelled: cancelled_clone, + error: false, + }; + tokio::io::copy(&mut stdout_opt, &mut sender) + .await + .expect("TODO: handle this"); + }); + + let contact_clone = contact.clone(); + let cancelled_clone = cancelled.clone(); + tokio::task::spawn(async move { + let mut sender = CmdWriter { + channel, + contact: contact_clone, + cancelled: cancelled_clone, + error: true, + }; + tokio::io::copy(&mut stderr_opt, &mut sender) + .await + .expect("TODO: handle this"); + }); + + let contact_clone = contact.clone(); + let cancelled_clone = cancelled.clone(); + tokio::task::spawn(async move { + let exit_status: i32; + loop { + if let Some(exit_code) = child.try_wait().expect("TODO: handle this") { + // TODO: is defaulting to -1 correct? + // #[cfg(target_family = "unix")] + // exit_status = std::os::unix::process::ExitStatusExt::into_raw(exit_code); + // #[cfg(not(target_family = "unix"))] + exit_status = exit_code.code().unwrap_or(-1); + break; + } + + if cancelled_clone.load(std::sync::atomic::Ordering::SeqCst) { + child.kill().await.expect("TODO: handle this"); + exit_status = -1; + break; + } + + // Yield to not block event loop with busy loop + tokio::task::yield_now().await; + } + + if contact_clone + .send(ChannelMessage::ProcessDead(exit_status)) + .is_err() + { + error!("Proc recv'ing channel was dropped before process dead alert was sent") + } + }); + + Ok(Proc { + channel, + contact, + cancelled, + stdin, + }) + } + + pub fn cancel(&mut self) { + self.cancelled + .store(true, std::sync::atomic::Ordering::SeqCst); + } + + pub async fn write(&mut self, src: &[u8]) -> Result<()> { + Ok(self.stdin.write_all(src).await?) + } +} diff --git a/src/database.rs b/src/database.rs index 26c632e..881a9c3 100644 --- a/src/database.rs +++ b/src/database.rs @@ -9,10 +9,8 @@ pub static DATABASE: OnceCell = OnceCell::const_new // TODO: allow disabling of db at runtime as well as compile time pub async fn setup() -> Result<()> { - let db_url; - - match std::env::var("HOMEVAL_DB") { - Ok(url) => db_url = url, + let db_url = match std::env::var("HOMEVAL_DB") { + Ok(url) => url, Err(err) => { warn!( "Encountered error fetching $HOMEVAL_DB: `{}`. Disabling database integration.", @@ -20,7 +18,7 @@ pub async fn setup() -> Result<()> { ); return Ok(()); } - } + }; let connect_options = ConnectOptions::new(db_url) .acquire_timeout(Duration::from_secs(5)) diff --git a/src/main.rs b/src/main.rs index 8723d24..be04797 100644 --- a/src/main.rs +++ b/src/main.rs @@ -68,8 +68,8 @@ static LAST_SESSION_USING_CHANNEL: LazyLock>> = // RwLock>>>, // > = LazyLock::new(|| RwLock::new(HashMap::new())); -// static CHILD_PROCS_ENV_BASE: LazyLock>> = -// LazyLock::new(|| RwLock::new(HashMap::new())); +static CHILD_PROCS_ENV_BASE: LazyLock>> = + LazyLock::new(|| RwLock::new(HashMap::new())); #[cfg(feature = "database")] mod database; diff --git a/src/parse_paseto.rs b/src/parse_paseto.rs index d96f1c4..c366338 100644 --- a/src/parse_paseto.rs +++ b/src/parse_paseto.rs @@ -1,12 +1,10 @@ use anyhow::Result; use base64::{engine::general_purpose, Engine as _}; use homeval_services::ClientInfo; +use pasetors::{token::UntrustedToken, version2::V2, Public}; use prost::Message; use std::io::Error; -#[cfg(feature = "verify_connections")] -use pasetors; - #[cfg(feature = "verify_connections")] static KEYS: tokio::sync::OnceCell> = tokio::sync::OnceCell::const_new(); @@ -14,21 +12,31 @@ static KEYS: tokio::sync::OnceCell> = #[cfg(feature = "verify_connections")] use log::{as_display, warn}; -fn parse_noverify(token: &str) -> Result<(Vec, bool)> { - let token_parts = token.split('.').collect::>(); - if token_parts.len() < 3 { - return Err(Error::new(std::io::ErrorKind::InvalidData, "Invalid Token").into()); - } - - if token_parts[0] != "v2" || token_parts[1] != "public" { - return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid Token").into()); - } - - let decoded = general_purpose::URL_SAFE_NO_PAD.decode(token_parts[2].as_bytes())?; - let decoded_len = decoded.len(); - // currently doesn't verify signature - let (msg, _sig) = decoded.split_at(decoded_len - 64); - Ok((msg.to_vec(), false)) +fn parse_noverify(input: &str) -> Result<(Vec, bool)> { + let token: UntrustedToken = match UntrustedToken::try_from(input) { + Ok(token) => token, + Err(_err) => { + return Err(Error::new( + std::io::ErrorKind::InvalidData, + "Parsing error on paseto token", + ) + .into()) + } + }; + // let token_parts = token.split('.').collect::>(); + // if token_parts.len() < 3 { + // return Err(Error::new(std::io::ErrorKind::InvalidData, "Invalid Token").into()); + // } + + // if token_parts[0] != "v2" || token_parts[1] != "public" { + // return Err(std::io::Error::new(std::io::ErrorKind::InvalidData, "Invalid Token").into()); + // } + + // let decoded = general_purpose::URL_SAFE_NO_PAD.decode(token_parts[2].as_bytes())?; + // let decoded_len = decoded.len(); + // // currently doesn't verify signature + // let (msg, _sig) = decoded.split_at(decoded_len - 64); + Ok((token.untrusted_payload().to_vec(), false)) } #[cfg(feature = "verify_connections")] @@ -47,10 +55,8 @@ async fn init_keys() -> Result> { #[cfg(feature = "verify_connections")] async fn parse_verify(input: &str) -> Result<(Vec, bool)> { let keys = KEYS.get_or_try_init(init_keys).await?; - let token: pasetors::token::UntrustedToken; - - match pasetors::token::UntrustedToken::try_from(input) { - Ok(_token) => token = _token, + let token = match pasetors::token::UntrustedToken::try_from(input) { + Ok(token) => token, Err(_err) => { return Err(Error::new( std::io::ErrorKind::InvalidData, @@ -58,7 +64,7 @@ async fn parse_verify(input: &str) -> Result<(Vec, bool)> { ) .into()) } - } + }; let _authority = general_purpose::STANDARD.decode(token.untrusted_footer())?; let authority = goval::GovalSigningAuthority::decode(_authority.as_slice())?; @@ -96,10 +102,8 @@ async fn parse_verify(input: &str) -> Result<(Vec, bool)> { .into()); } - let result; - - match pasetors::version2::PublicToken::verify(&pubkey, &token, None) { - Ok(trusted) => result = trusted, + let result = match pasetors::version2::PublicToken::verify(&pubkey, &token, None) { + Ok(trusted) => trusted, Err(err) => { return Err(Error::new( std::io::ErrorKind::InvalidData, @@ -107,7 +111,7 @@ async fn parse_verify(input: &str) -> Result<(Vec, bool)> { ) .into()); } - } + }; Ok((result.payload().as_bytes().to_vec(), true)) } diff --git a/src/repldb_server.rs b/src/repldb_server.rs index d5475de..977364a 100644 --- a/src/repldb_server.rs +++ b/src/repldb_server.rs @@ -13,7 +13,7 @@ use serde::Deserialize; use std::{collections::HashMap, net::TcpListener}; pub async fn start_server() -> Result<()> { - if let None = crate::DATABASE.get() { + if crate::DATABASE.get().is_none() { warn!("Database missing, disabling repldb server."); return Ok(()); } @@ -127,11 +127,10 @@ struct ListKeys { } async fn list_keys(Query(__prefix): Query) -> (StatusCode, String) { - let prefix; - match __prefix.prefix { - Some(_prefix) => prefix = _prefix, + let prefix = match __prefix.prefix { + Some(prefix) => prefix, None => return (StatusCode::OK, "".to_string()), - } + }; let database = crate::DATABASE .get() From 507fce3db6fa43fd9b9ac4555b0c2f4adf76e648 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 14 Jan 2024 01:12:59 +0000 Subject: [PATCH 027/103] build(deps):(deps): bump webpki from 0.22.0 to 0.22.4 Bumps [webpki](https://github.com/briansmith/webpki) from 0.22.0 to 0.22.4. - [Commits](https://github.com/briansmith/webpki/commits) --- updated-dependencies: - dependency-name: webpki dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 021218c..ba2131c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2062,12 +2062,26 @@ dependencies = [ "cc", "libc", "once_cell", - "spin", - "untrusted", + "spin 0.5.2", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e" +dependencies = [ + "cc", + "getrandom 0.2.10", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + [[package]] name = "rkyv" version = "0.7.42" @@ -2145,7 +2159,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" dependencies = [ "log", - "ring", + "ring 0.16.20", "sct", "webpki", ] @@ -2201,8 +2215,8 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" dependencies = [ - "ring", - "untrusted", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -2636,6 +2650,12 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "sqlformat" version = "0.2.1" @@ -3277,6 +3297,12 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.4.0" @@ -3454,12 +3480,12 @@ dependencies = [ [[package]] name = "webpki" -version = "0.22.0" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring", - "untrusted", + "ring 0.17.3", + "untrusted 0.9.0", ] [[package]] From bf98332cd095df2cf8e26ec057d5958f75432366 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 13 Jan 2024 17:21:40 -0800 Subject: [PATCH 028/103] fix(dependabot): Fix config --- .github/dependabot.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a491041..ad268ff 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -7,7 +7,7 @@ updates: assignees: - "PotentialStyx" commit-message: - prefix: "build(deps):" + prefix: "build" include: "scope" labels: - "cargo" From 1af3ae9ddaa87b9a95f75727a18edc53a1a83000 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 13 Jan 2024 17:24:57 -0800 Subject: [PATCH 029/103] build(deps): Update everything --- Cargo.lock | 1265 ++++++++++++++++++++++++++++------------------------ 1 file changed, 686 insertions(+), 579 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba2131c..0a1b1ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,33 +8,49 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "ahash" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.12", "once_cell", "version_check", ] [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if", "once_cell", "version_check", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.0.2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" dependencies = [ "memchr", ] @@ -47,9 +63,9 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] name = "allocator-api2" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56fc6cf8dc8c4158eed8649f9b8b0ea1518eb62b544fe9490d66fa0b349eafe9" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" [[package]] name = "android-tzdata" @@ -68,9 +84,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.71" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "arrayvec" @@ -97,18 +113,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.48", ] [[package]] name = "async-trait" -version = "0.1.68" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.48", ] [[package]] @@ -128,14 +144,14 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8175979259124331c1d7bf6586ee7e0da434155e4b2d48ec2c8386281d8df39" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", - "base64 0.21.2", - "bitflags", + "base64 0.21.7", + "bitflags 1.3.2", "bytes", "futures-util", "http", @@ -178,6 +194,21 @@ dependencies = [ "tower-service", ] +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "bae" version = "0.1.7" @@ -205,9 +236,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "bigdecimal" @@ -226,6 +257,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "bitvec" version = "1.0.1" @@ -249,54 +286,33 @@ dependencies = [ [[package]] name = "borsh" -version = "0.10.3" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" +checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667" dependencies = [ "borsh-derive", - "hashbrown 0.13.2", + "cfg_aliases", ] [[package]] name = "borsh-derive" -version = "0.10.3" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" +checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd" dependencies = [ - "borsh-derive-internal", - "borsh-schema-derive-internal", + "once_cell", "proc-macro-crate", - "proc-macro2", - "syn 1.0.109", -] - -[[package]] -name = "borsh-derive-internal" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" -dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", -] - -[[package]] -name = "borsh-schema-derive-internal" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "syn 2.0.48", + "syn_derive", ] [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecheck" @@ -322,21 +338,24 @@ dependencies = [ [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "cfg-if" @@ -344,25 +363,31 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "chrono" -version = "0.4.26" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +checksum = "d87d9d13be47a5b7c3907137f1290b0459a7f80efb26be8c52afb11963bccb02" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", "time 0.1.45", - "winapi", + "windows-targets 0.48.5", ] [[package]] name = "chrono-tz" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9cc2b23599e6d7479755f3594285efb3f74a1bdca7a7374948bc831e23a552" +checksum = "91d7b79e99bfaa0d47da0687c43aa3b7381938a62ad3a6498599039321f660b7" dependencies = [ "chrono", "chrono-tz-build", @@ -371,9 +396,9 @@ dependencies = [ [[package]] name = "chrono-tz-build" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9998fb9f7e9b2111641485bf8beb32f92945f97f92a3d061f744cfef335f751" +checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" dependencies = [ "parse-zoneinfo", "phf", @@ -386,7 +411,7 @@ version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ - "bitflags", + "bitflags 1.3.2", "clap_derive", "clap_lex", "indexmap 1.9.3", @@ -418,9 +443,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -428,9 +453,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "cpu-time" @@ -444,9 +469,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.8" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03e69e28e9f7f77debdedbaafa2866e1de9ba56df55a8bd7cfc724c25a09987c" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -462,32 +487,27 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-queue" -version = "0.3.8" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" dependencies = [ - "cfg-if", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crypto-common" @@ -505,6 +525,12 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3b7eb4404b8195a9abb6356f4ac07d8ba267045c8d6d220ac4dc992e6cc75df" +[[package]] +name = "data-encoding" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + [[package]] name = "deadqueue" version = "0.2.4" @@ -515,6 +541,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + [[package]] name = "digest" version = "0.10.7" @@ -560,18 +596,18 @@ checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" [[package]] name = "ed25519-compact" -version = "2.0.4" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3d382e8464107391c8706b4c14b087808ecb909f6c15c34114bc42e53a9e4c" +checksum = "a667e6426df16c2ac478efa4a439d0e674cba769c5556e8cf221739251640c8c" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.12", ] [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "entity" @@ -595,38 +631,27 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.3.25" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2b0c2380453a92ea8b6c8e5f64ecaafccddde8ceab55ff7a8ac1029f894569" +checksum = "55d05712b2d8d88102bc9868020c9e5c7a1f5527c452b9b97450a1d006140ba7" dependencies = [ "serde", ] [[package]] name = "errno" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ - "cc", "libc", + "windows-sys 0.52.0", ] [[package]] @@ -637,18 +662,15 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fastrand" -version = "1.9.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fiat-crypto" -version = "0.1.20" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" [[package]] name = "file-id" @@ -672,16 +694,22 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.21" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.2.16", - "windows-sys 0.48.0", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", ] +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + [[package]] name = "fixedbitset" version = "0.4.2" @@ -711,9 +739,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -735,9 +763,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -750,9 +778,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -760,15 +788,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -788,38 +816,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-macro" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.48", ] [[package]] name = "futures-sink" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-util" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -856,9 +884,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "js-sys", @@ -867,11 +895,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + [[package]] name = "h2" -version = "0.3.20" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "b553656127a00601c8ae5590fcfdc118e4083a7924b6cf4ffc1ea4b99dc429d7" dependencies = [ "bytes", "fnv", @@ -879,7 +913,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.1.0", "slab", "tokio", "tokio-util", @@ -892,35 +926,26 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.7", ] [[package]] name = "hashbrown" -version = "0.13.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ - "ahash 0.8.3", -] - -[[package]] -name = "hashbrown" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" -dependencies = [ - "ahash 0.8.3", + "ahash 0.8.7", "allocator-api2", ] [[package]] name = "hashlink" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312f66718a2d7789ffef4f4b7b213138ed9f1eb3aa1d0d82fc99f88fb3ffd26f" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.0", + "hashbrown 0.14.3", ] [[package]] @@ -943,18 +968,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "hex" @@ -964,9 +980,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac", ] @@ -980,13 +996,22 @@ dependencies = [ "digest", ] +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "homeval" version = "0.3.0" dependencies = [ "anyhow", "axum", - "base64 0.21.2", + "base64 0.21.7", "chrono", "chrono-tz", "cpu-time", @@ -1011,14 +1036,14 @@ dependencies = [ "services", "textnonce", "tokio", - "toml 0.7.5", + "toml", ] [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -1027,9 +1052,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -1044,9 +1069,9 @@ checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" @@ -1056,9 +1081,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -1093,16 +1118,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.57" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows", + "windows-core", ] [[package]] @@ -1116,9 +1141,9 @@ dependencies = [ [[package]] name = "idna" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" dependencies = [ "unicode-bidi", "unicode-normalization", @@ -1136,12 +1161,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.3", ] [[package]] @@ -1150,7 +1175,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" dependencies = [ - "bitflags", + "bitflags 1.3.2", "inotify-sys", "libc", ] @@ -1173,17 +1198,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.1", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ioctl-rs" version = "0.1.6" @@ -1195,14 +1209,13 @@ dependencies = [ [[package]] name = "is-terminal" -version = "0.4.7" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", + "hermit-abi", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1214,26 +1227,35 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] [[package]] name = "kqueue" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c8fc60ba15bf51257aa9807a48a61013db043fcf3a78cb0d916e8e396dcad98" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" dependencies = [ "kqueue-sys", "libc", @@ -1241,11 +1263,11 @@ dependencies = [ [[package]] name = "kqueue-sys" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" dependencies = [ - "bitflags", + "bitflags 1.3.2", "libc", ] @@ -1257,21 +1279,32 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "libredox" +version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall 0.4.1", +] [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" dependencies = [ "autocfg", "scopeguard", @@ -1279,9 +1312,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.19" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" dependencies = [ "serde", "value-bag", @@ -1293,29 +1326,30 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" dependencies = [ - "regex-automata", + "regex-automata 0.1.10", ] [[package]] name = "matchit" -version = "0.7.0" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "md-5" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6365506850d44bff6e2fbcb5176cf63650e48bd45ef2fe2665ae1570e0f4b9ca" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ + "cfg-if", "digest", ] [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memoffset" @@ -1346,11 +1380,20 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "mio" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "log", @@ -1389,7 +1432,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" dependencies = [ "autocfg", - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "memoffset", @@ -1408,20 +1451,21 @@ dependencies = [ [[package]] name = "notify" -version = "6.0.1" +version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5738a2795d57ea20abec2d6d76c6081186709c0024187cd5977265eda6598b51" +checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags", + "bitflags 2.4.1", "crossbeam-channel", "filetime", "fsevent-sys", "inotify", "kqueue", "libc", + "log", "mio", "walkdir", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1438,9 +1482,9 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" dependencies = [ "autocfg", "num-integer", @@ -1459,36 +1503,45 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.2.6", + "hermit-abi", "libc", ] +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl" -version = "0.10.55" +version = "0.10.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345df152bc43501c5eb9e4654ff05f794effb78d4efe3d53abc158baddc0703d" +checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" dependencies = [ - "bitflags", + "bitflags 2.4.1", "cfg-if", "foreign-types", "libc", @@ -1505,7 +1558,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.48", ] [[package]] @@ -1516,9 +1569,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.90" +version = "0.9.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374533b0e45f3a7ced10fcaeccca020e66656bc03dac384f852e4e5a7a8104a6" +checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" dependencies = [ "cc", "libc", @@ -1528,9 +1581,9 @@ dependencies = [ [[package]] name = "orion" -version = "0.17.4" +version = "0.17.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbe74a766292f94f7e69db5a7bf010eadd944f24186c463fe578a7e637582066" +checksum = "7abdb10181903c8c4b016ba45d6d6d5af1a1e2a461aa4763a83b87f5df4695e5" dependencies = [ "fiat-crypto", "subtle", @@ -1539,9 +1592,9 @@ dependencies = [ [[package]] name = "os_str_bytes" -version = "6.5.1" +version = "6.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d5d9eb14b174ee9aa2ef96dc2b94637a2d4b6e7cb873c7e171f0c20c6cf3eac" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] name = "ouroboros" @@ -1584,7 +1637,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", + "parking_lot_core 0.9.9", ] [[package]] @@ -1603,15 +1656,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "smallvec", - "windows-targets 0.48.0", + "windows-targets 0.48.5", ] [[package]] @@ -1625,13 +1678,13 @@ dependencies = [ [[package]] name = "pasetors" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba765699a309908d55950919a3445e9491453e89b2587b1b2abe4143a48894c0" +checksum = "6b36d47c66f2230dd1b7143d9afb2b4891879020210eddf2ccb624e529b96dba" dependencies = [ "ct-codecs", "ed25519-compact", - "getrandom 0.2.10", + "getrandom 0.2.12", "orion", "subtle", "zeroize", @@ -1639,24 +1692,24 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "petgraph" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 1.9.3", + "indexmap 2.1.0", ] [[package]] @@ -1699,29 +1752,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95a7476719eab1e366eaf73d0260af3021184f18177925b07f54b30089ceead" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.0" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39407670928234ebc5e6e580247dd567ad73a3578460c5990f9503df207e8f07" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.48", ] [[package]] name = "pin-project-lite" -version = "0.2.9" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" [[package]] name = "pin-utils" @@ -1731,9 +1784,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" [[package]] name = "portable-pty" @@ -1742,7 +1795,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "806ee80c2a03dbe1a9fb9534f8d19e4c0546b790cde8fd1fea9d6390644cb0be" dependencies = [ "anyhow", - "bitflags", + "bitflags 1.3.2", "downcast-rs", "filedescriptor", "lazy_static", @@ -1756,6 +1809,12 @@ dependencies = [ "winreg", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1774,11 +1833,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "0.1.5" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +checksum = "6b2685dd208a3771337d8d386a89840f0f43cd68be8dae90a5f8c2384effc9cd" dependencies = [ - "toml 0.5.11", + "toml_edit 0.21.0", ] [[package]] @@ -1807,9 +1866,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] @@ -1832,7 +1891,7 @@ checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes", "heck 0.4.1", - "itertools", + "itertools 0.10.5", "lazy_static", "log", "multimap", @@ -1853,7 +1912,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.5", "proc-macro2", "quote", "syn 1.0.109", @@ -1899,9 +1958,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.28" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1971,7 +2030,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.10", + "getrandom 0.2.12", ] [[package]] @@ -1989,38 +2048,39 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "redox_syscall" -version = "0.3.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" dependencies = [ - "getrandom 0.2.10", - "redox_syscall 0.2.16", + "getrandom 0.2.12", + "libredox", "thiserror", ] [[package]] name = "regex" -version = "1.8.4" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.7.2", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", ] [[package]] @@ -2032,6 +2092,17 @@ dependencies = [ "regex-syntax 0.6.29", ] +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.2", +] + [[package]] name = "regex-syntax" version = "0.6.29" @@ -2040,15 +2111,15 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rend" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581008d2099240d37fb08d77ad713bcaec2c4d89d50b5b21a8bb1996bbab68ab" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" dependencies = [ "bytecheck", ] @@ -2070,12 +2141,12 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.3" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babe80d5c16becf6594aa32ad2be8fe08498e7ae60b77de8df700e67f191d7e" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" dependencies = [ "cc", - "getrandom 0.2.10", + "getrandom 0.2.12", "libc", "spin 0.9.8", "untrusted 0.9.0", @@ -2084,12 +2155,13 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.42" +version = "0.7.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0200c8230b013893c0b2d6213d6ec64ed2b9be2e0e016682b7224ff82cff5c58" +checksum = "527a97cdfef66f65998b5f3b637c26f5a5ec09cc52a3f9932313ac645f4190f5" dependencies = [ "bitvec", "bytecheck", + "bytes", "hashbrown 0.12.3", "ptr_meta", "rend", @@ -2101,9 +2173,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.42" +version = "0.7.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2e06b915b5c230a17d7a736d1e2e63ee753c256a8614ef3f5147b13a4f5541d" +checksum = "b5c462a1328c8e67e4d6dbad1eb0355dd43e8ab432c6e227a43657f16ade5033" dependencies = [ "proc-macro2", "quote", @@ -2112,9 +2184,9 @@ dependencies = [ [[package]] name = "ropey" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53ce7a2c43a32e50d666e33c5a80251b31147bb4b49024bcab11fb6f20c671ed" +checksum = "93411e420bcd1a75ddd1dc3caf18c23155eda2c090631a85af21ba19e97093b5" dependencies = [ "smallvec", "str_indices", @@ -2122,14 +2194,12 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.30.0" +version = "1.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0446843641c69436765a35a5a77088e28c2e6a12da93e84aa3ab1cd4aa5a042" +checksum = "06676aec5ccb8fc1da723cc8c0f9a46549f21ebb8753d3915c6c41db1e7f1dc4" dependencies = [ "arrayvec", "borsh", - "bytecheck", - "byteorder", "bytes", "num-traits", "rand 0.8.5", @@ -2138,25 +2208,30 @@ dependencies = [ "serde_json", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustix" -version = "0.37.20" +version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "bitflags", + "bitflags 2.4.1", "errno", - "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" dependencies = [ "log", "ring 0.16.20", @@ -2166,24 +2241,24 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.2", + "base64 0.21.7", ] [[package]] name = "rustversion" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.13" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "same-file" @@ -2196,27 +2271,27 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" dependencies = [ - "windows-sys 0.42.0", + "windows-sys 0.52.0", ] [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring 0.17.7", + "untrusted 0.9.0", ] [[package]] @@ -2241,7 +2316,7 @@ dependencies = [ "serde_json", "sqlx", "thiserror", - "time 0.3.22", + "time 0.3.31", "tracing", "url", "uuid", @@ -2304,7 +2379,7 @@ dependencies = [ "rust_decimal", "sea-query-derive", "serde_json", - "time 0.3.22", + "time 0.3.31", "uuid", ] @@ -2320,7 +2395,7 @@ dependencies = [ "sea-query", "serde_json", "sqlx", - "time 0.3.22", + "time 0.3.31", "uuid", ] @@ -2390,11 +2465,11 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "security-framework" -version = "2.9.1" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -2403,9 +2478,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" dependencies = [ "core-foundation-sys", "libc", @@ -2413,22 +2488,22 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.164" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.164" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.48", ] [[package]] @@ -2442,9 +2517,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.99" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46266871c240a00b8f503b877622fe33430b3c7d963bdc0f2adc511e54a1eae3" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -2453,18 +2528,19 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.11" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7f05c1d5476066defcdfacce1f52fc3cae3af1d3089727100c02ae92e5abbe0" +checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" dependencies = [ + "itoa", "serde", ] [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] @@ -2547,9 +2623,9 @@ dependencies = [ [[package]] name = "sha1" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", @@ -2558,9 +2634,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -2569,9 +2645,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -2609,39 +2685,39 @@ checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" [[package]] name = "similar" -version = "2.2.1" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" +checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21" [[package]] name = "siphasher" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" [[package]] name = "slab" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" dependencies = [ "autocfg", ] [[package]] name = "smallvec" -version = "1.10.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" [[package]] name = "socket2" -version = "0.4.9" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -2658,11 +2734,11 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "sqlformat" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e" +checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" dependencies = [ - "itertools", + "itertools 0.12.0", "nom", "unicode_categories", ] @@ -2683,11 +2759,11 @@ version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" dependencies = [ - "ahash 0.7.6", + "ahash 0.7.7", "atoi", "base64 0.13.1", "bigdecimal", - "bitflags", + "bitflags 1.3.2", "byteorder", "bytes", "chrono", @@ -2727,7 +2803,7 @@ dependencies = [ "sqlx-rt", "stringprep", "thiserror", - "time 0.3.22", + "time 0.3.31", "tokio-stream", "url", "uuid", @@ -2767,16 +2843,17 @@ dependencies = [ [[package]] name = "str_indices" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f026164926842ec52deb1938fae44f83dfdb82d0a5b0270c5bd5935ab74d6dd" +checksum = "e9557cb6521e8d009c51a8666f09356f4b817ba9ba0981a305bd86aee47bd35c" [[package]] name = "stringprep" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" dependencies = [ + "finl_unicode", "unicode-bidi", "unicode-normalization", ] @@ -2789,15 +2866,15 @@ checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" [[package]] name = "sval" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b031320a434d3e9477ccf9b5756d57d4272937b8d22cb88af80b7633a1b78b1" +checksum = "1604e9ab506f4805bc62d2868c6d20f23fa6ced4c7cfe695a1d20589ba5c63d0" [[package]] name = "sval_buffer" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bf7e9412af26b342f3f2cc5cc4122b0105e9d16eb76046cd14ed10106cf6028" +checksum = "2831b6451148d344f612016d4277348f7721b78a0869a145fd34ef8b06b3fa2e" dependencies = [ "sval", "sval_ref", @@ -2805,18 +2882,18 @@ dependencies = [ [[package]] name = "sval_dynamic" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0ef628e8a77a46ed3338db8d1b08af77495123cc229453084e47cd716d403cf" +checksum = "238ac5832a23099a413ffd22e66f7e6248b9af4581b64c758ca591074be059fc" dependencies = [ "sval", ] [[package]] name = "sval_fmt" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dc09e9364c2045ab5fa38f7b04d077b3359d30c4c2b3ec4bae67a358bd64326" +checksum = "c8474862431bac5ac7aee8a12597798e944df33f489c340e17e886767bda0c4e" dependencies = [ "itoa", "ryu", @@ -2825,34 +2902,44 @@ dependencies = [ [[package]] name = "sval_json" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ada6f627e38cbb8860283649509d87bc4a5771141daa41c78fd31f2b9485888d" +checksum = "d8f348030cc3d2a11eb534145600601f080cf16bf9ec0783efecd2883f14c21e" dependencies = [ "itoa", "ryu", "sval", ] +[[package]] +name = "sval_nested" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6659c3f6be1e5e99dc7c518877f48a8a39088ace2504b046db789bd78ce5969d" +dependencies = [ + "sval", + "sval_buffer", + "sval_ref", +] + [[package]] name = "sval_ref" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703ca1942a984bd0d9b5a4c0a65ab8b4b794038d080af4eb303c71bc6bf22d7c" +checksum = "829ad319bd82d0da77be6f3d547623686c453502f8eebdeb466cfa987972bd28" dependencies = [ "sval", ] [[package]] name = "sval_serde" -version = "2.6.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830926cd0581f7c3e5d51efae4d35c6b6fc4db583842652891ba2f1bed8db046" +checksum = "1a9da6c3efaedf8b8c0861ec5343e8e8c51d838f326478623328bd8728b79bca" dependencies = [ "serde", "sval", - "sval_buffer", - "sval_fmt", + "sval_nested", ] [[package]] @@ -2868,15 +2955,27 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.22" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2efbeae7acf4eabd6bcdcbd11c92f45231ddda7539edc7806bd1a04a03b24616" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "sync_wrapper" version = "0.1.2" @@ -2891,23 +2990,22 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.6.0" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" dependencies = [ - "autocfg", "cfg-if", "fastrand", - "redox_syscall 0.3.5", + "redox_syscall 0.4.1", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "termcolor" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] @@ -2939,22 +3037,22 @@ checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.48", ] [[package]] @@ -2980,11 +3078,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.22" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" dependencies = [ + "deranged", "itoa", + "powerfmt", "serde", "time-core", "time-macros", @@ -2992,15 +3092,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.9" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" dependencies = [ "time-core", ] @@ -3022,11 +3122,11 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.28.2" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ - "autocfg", + "backtrace", "bytes", "libc", "mio", @@ -3041,13 +3141,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.48", ] [[package]] @@ -3084,9 +3184,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.18.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54319c93411147bced34cb5609a80e0a8e44c5999c93903a81cd866630ec0bfd" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", @@ -3096,9 +3196,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.8" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", @@ -3110,43 +3210,45 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.11" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.19.15", ] [[package]] -name = "toml" -version = "0.7.5" +name = "toml_datetime" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebafdf5ad1220cb59e7d17cf4d2c72015297b75b19a10472f99b89225089240" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", ] [[package]] -name = "toml_datetime" -version = "0.6.3" +name = "toml_edit" +version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ + "indexmap 2.1.0", "serde", + "serde_spanned", + "toml_datetime", + "winnow", ] [[package]] name = "toml_edit" -version = "0.19.11" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266f016b7f039eec8a1a80dfe6156b633d208b9fccca5e4db1d6775b0c4e34a7" +checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ - "indexmap 2.0.0", - "serde", - "serde_spanned", + "indexmap 2.1.0", "toml_datetime", "winnow", ] @@ -3181,11 +3283,10 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "cfg-if", "log", "pin-project-lite", "tracing-attributes", @@ -3194,29 +3295,29 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.48", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", ] [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers", "once_cell", @@ -3229,19 +3330,19 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" -version = "0.18.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ee6ab729cd4cf0fd55218530c4522ed30b7b6081752839b68fcec8d0960788" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" dependencies = [ - "base64 0.13.1", "byteorder", "bytes", + "data-encoding", "http", "httparse", "log", @@ -3254,21 +3355,21 @@ dependencies = [ [[package]] name = "typenum" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" @@ -3305,9 +3406,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", "idna", @@ -3322,18 +3423,18 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "uuid" -version = "1.4.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d023da39d1fde5a8a3fe1f3e01ca9632ada0a63e9797de55a879d6e2236277be" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" dependencies = [ "serde", ] [[package]] name = "value-bag" -version = "1.4.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92ccd67fb88503048c01b59152a04effd0782d035a83a6d256ce6085f08f4a3" +checksum = "7cdbaf5e132e593e9fc1de6a15bbec912395b11fb9719e061cf64f804524c503" dependencies = [ "value-bag-serde1", "value-bag-sval2", @@ -3341,9 +3442,9 @@ dependencies = [ [[package]] name = "value-bag-serde1" -version = "1.4.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0b9f3feef403a50d4d67e9741a6d8fc688bcbb4e4f31bd4aab72cc690284394" +checksum = "92cad98b1b18d06b6f38b3cd04347a9d7a3a0111441a061f71377fb6740437e4" dependencies = [ "erased-serde", "serde", @@ -3352,9 +3453,9 @@ dependencies = [ [[package]] name = "value-bag-sval2" -version = "1.4.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b24f4146b6f3361e91cbf527d1fb35e9376c3c0cef72ca5ec5af6d640fad7d" +checksum = "3dc7271d6b3bf58dd2e610a601c0e159f271ffdb7fbb21517c40b52138d64f8e" dependencies = [ "sval", "sval_buffer", @@ -3379,9 +3480,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.3.3" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", "winapi-util", @@ -3416,9 +3517,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3426,24 +3527,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.48", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3451,28 +3552,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ "js-sys", "wasm-bindgen", @@ -3484,7 +3585,7 @@ version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring 0.17.3", + "ring 0.17.7", "untrusted 0.9.0", ] @@ -3499,13 +3600,14 @@ dependencies = [ [[package]] name = "which" -version = "4.4.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" dependencies = [ "either", - "libc", + "home", "once_cell", + "rustix", ] [[package]] @@ -3536,9 +3638,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -3550,166 +3652,151 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "windows" -version = "0.48.0" +name = "windows-core" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.52.0", ] [[package]] name = "windows-sys" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows-targets 0.48.5", ] [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.52.0", ] [[package]] name = "windows-targets" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" [[package]] name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" [[package]] name = "windows_i686_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" [[package]] name = "windows_i686_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" [[package]] name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" [[package]] name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.4.7" +version = "0.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0ace3845f0d96209f0375e6d367e3eb87eb65d27d445bdc9f1843a26f39448" +checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" dependencies = [ "memchr", ] @@ -3732,8 +3819,28 @@ dependencies = [ "tap", ] +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" From 7e96aa6555f9c2aa46f1ac11b8e5be5fa9eca1d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 14 Jan 2024 01:26:23 +0000 Subject: [PATCH 030/103] build(deps): bump prost from 0.11.9 to 0.12.3 Bumps [prost](https://github.com/tokio-rs/prost) from 0.11.9 to 0.12.3. - [Release notes](https://github.com/tokio-rs/prost/releases) - [Commits](https://github.com/tokio-rs/prost/compare/v0.11.9...v0.12.3) --- updated-dependencies: - dependency-name: prost dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 35 +++++++++++++++++++++++++++++------ Cargo.toml | 2 +- protobuf/Cargo.toml | 2 +- services/Cargo.toml | 2 +- 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ba2131c..5003945 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1001,7 +1001,7 @@ dependencies = [ "log", "migration", "pasetors", - "prost", + "prost 0.12.3", "prost-types", "protobuf", "sea-orm", @@ -1821,7 +1821,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" dependencies = [ "bytes", - "prost-derive", + "prost-derive 0.11.9", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive 0.12.3", ] [[package]] @@ -1838,7 +1848,7 @@ dependencies = [ "multimap", "petgraph", "prettyplease", - "prost", + "prost 0.11.9", "prost-types", "regex", "syn 1.0.109", @@ -1859,20 +1869,33 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 2.0.22", +] + [[package]] name = "prost-types" version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" dependencies = [ - "prost", + "prost 0.11.9", ] [[package]] name = "protobuf" version = "0.2.0" dependencies = [ - "prost", + "prost 0.12.3", "prost-build", "prost-types", ] @@ -2535,7 +2558,7 @@ dependencies = [ "log", "notify-debouncer-full", "portable-pty", - "prost", + "prost 0.12.3", "prost-types", "protobuf", "ropey", diff --git a/Cargo.toml b/Cargo.toml index d72ab67..b338eb4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ env_logger = { git = "https://github.com/tmccombs/env_logger", rev = "a47d1d99", futures-channel = "0.3.26" futures-util = "0.3.26" log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } -prost = "0.11.8" +prost = "0.12.3" prost-types = "0.11.8" serde_json = "1.0.97" serde = { version = "1.0.162", features = ["derive"] } diff --git a/protobuf/Cargo.toml b/protobuf/Cargo.toml index bf74814..be3f768 100644 --- a/protobuf/Cargo.toml +++ b/protobuf/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -prost = "0.11.8" +prost = "0.12.3" prost-types = "0.11.8" [build-dependencies] diff --git a/services/Cargo.toml b/services/Cargo.toml index f98f524..50cd370 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -15,7 +15,7 @@ goval = { package = "protobuf", path = "../protobuf"} log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } notify-debouncer-full = { version = "0.2.0", default-features = false } portable-pty = "0.8.1" -prost = "0.11.9" +prost = "0.12.3" prost-types = "0.11.9" ropey = "1.6.0" serde = "1.0.164" From e6aa526d4c0bb013203ed7268fb43185ec05e3e4 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 13 Jan 2024 17:34:32 -0800 Subject: [PATCH 031/103] build(deps): Update prost fully --- Cargo.lock | 57 ++++++++++++++------------------------------- Cargo.toml | 2 +- protobuf/Cargo.toml | 4 ++-- services/Cargo.toml | 2 +- 4 files changed, 21 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f6d290..552d088 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1026,7 +1026,7 @@ dependencies = [ "log", "migration", "pasetors", - "prost 0.12.3", + "prost", "prost-types", "protobuf", "sea-orm", @@ -1823,12 +1823,12 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "prettyplease" -version = "0.1.25" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" dependencies = [ "proc-macro2", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] @@ -1873,16 +1873,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes", - "prost-derive 0.11.9", -] - [[package]] name = "prost" version = "0.12.3" @@ -1890,44 +1880,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" dependencies = [ "bytes", - "prost-derive 0.12.3", + "prost-derive", ] [[package]] name = "prost-build" -version = "0.11.9" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", "heck 0.4.1", "itertools 0.10.5", - "lazy_static", "log", "multimap", + "once_cell", "petgraph", "prettyplease", - "prost 0.11.9", + "prost", "prost-types", "regex", - "syn 1.0.109", + "syn 2.0.48", "tempfile", "which", ] -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "prost-derive" version = "0.12.3" @@ -1935,26 +1912,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", - "itertools", + "itertools 0.10.5", "proc-macro2", "quote", - "syn 2.0.22", + "syn 2.0.48", ] [[package]] name = "prost-types" -version = "0.11.9" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" dependencies = [ - "prost 0.11.9", + "prost", ] [[package]] name = "protobuf" version = "0.2.0" dependencies = [ - "prost 0.12.3", + "prost", "prost-build", "prost-types", ] @@ -2634,7 +2611,7 @@ dependencies = [ "log", "notify-debouncer-full", "portable-pty", - "prost 0.12.3", + "prost", "prost-types", "protobuf", "ropey", diff --git a/Cargo.toml b/Cargo.toml index b338eb4..49c15f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ futures-channel = "0.3.26" futures-util = "0.3.26" log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } prost = "0.12.3" -prost-types = "0.11.8" +prost-types = "0.12.3" serde_json = "1.0.97" serde = { version = "1.0.162", features = ["derive"] } tokio = {version="1.26.0", features = ["full"]} diff --git a/protobuf/Cargo.toml b/protobuf/Cargo.toml index be3f768..5d0be5b 100644 --- a/protobuf/Cargo.toml +++ b/protobuf/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] prost = "0.12.3" -prost-types = "0.11.8" +prost-types = "0.12.3" [build-dependencies] -prost-build = "0.11.8" +prost-build = "0.12.3" diff --git a/services/Cargo.toml b/services/Cargo.toml index 50cd370..97a9152 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -16,7 +16,7 @@ log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } notify-debouncer-full = { version = "0.2.0", default-features = false } portable-pty = "0.8.1" prost = "0.12.3" -prost-types = "0.11.9" +prost-types = "0.12.3" ropey = "1.6.0" serde = "1.0.164" serde_json = "1.0.97" From 86d9cdc9849d7e307c60c221aa92b1e94957aa82 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 13 Jan 2024 17:36:33 -0800 Subject: [PATCH 032/103] build(deps): Update toml --- Cargo.lock | 23 ++++++----------------- Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 552d088..c131db7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1837,7 +1837,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b2685dd208a3771337d8d386a89840f0f43cd68be8dae90a5f8c2384effc9cd" dependencies = [ - "toml_edit 0.21.0", + "toml_edit", ] [[package]] @@ -3210,14 +3210,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.8" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.19.15", + "toml_edit", ] [[package]] @@ -3229,19 +3229,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap 2.1.0", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - [[package]] name = "toml_edit" version = "0.21.0" @@ -3249,6 +3236,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ "indexmap 2.1.0", + "serde", + "serde_spanned", "toml_datetime", "winnow", ] diff --git a/Cargo.toml b/Cargo.toml index 49c15f4..d8744b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ futures = "0.3.28" axum = { version = "0.6.18", features = ["ws"] } cpu-time = "1.0.0" deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } -toml = "0.7.4" +toml = "0.8.8" textnonce = "1.0.0" From 64c450576149fb69d368a28ec81fd91494d37107 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 13 Jan 2024 18:02:25 -0800 Subject: [PATCH 033/103] build(deps): Update hyper to 1.1 This builds and should work, further testing might be needed to make sure there are no regressions. --- Cargo.lock | 111 +++++++++++++++++++++++++++++++++++++------- Cargo.toml | 8 ++-- src/parse_paseto.rs | 18 +++++-- 3 files changed, 112 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c131db7..3a073fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -154,9 +154,9 @@ dependencies = [ "bitflags 1.3.2", "bytes", "futures-util", - "http", - "http-body", - "hyper", + "http 0.2.11", + "http-body 0.4.6", + "hyper 0.14.28", "itoa", "matchit", "memchr", @@ -186,8 +186,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 0.2.11", + "http-body 0.4.6", "mime", "rustversion", "tower-layer", @@ -903,16 +903,16 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "h2" -version = "0.3.23" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b553656127a00601c8ae5590fcfdc118e4083a7924b6cf4ffc1ea4b99dc429d7" +checksum = "991910e35c615d8cab86b5ab04be67e6ad24d2bf5f4f11fdbbed26da999bbeab" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http", + "http 1.0.0", "indexmap 2.1.0", "slab", "tokio", @@ -1021,8 +1021,10 @@ dependencies = [ "futures", "futures-channel", "futures-util", - "hyper", + "http-body-util", + "hyper 1.1.0", "hyper-tls", + "hyper-util", "log", "migration", "pasetors", @@ -1050,6 +1052,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-body" version = "0.4.6" @@ -1057,7 +1070,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.11", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.0.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +dependencies = [ + "bytes", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -1089,9 +1125,8 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "http 0.2.11", + "http-body 0.4.6", "httparse", "httpdate", "itoa", @@ -1103,17 +1138,59 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http 1.0.0", + "http-body 1.0.0", + "httparse", + "itoa", + "pin-project-lite", + "tokio", + "want", +] + [[package]] name = "hyper-tls" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", - "hyper", + "http-body-util", + "hyper 1.1.0", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdea9aac0dbe5a9240d68cfd9501e2db94222c6dc06843e06640b9e07f0fdc67" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", + "hyper 1.1.0", + "pin-project-lite", + "socket2", + "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -3332,7 +3409,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.11", "httparse", "log", "rand 0.8.5", diff --git a/Cargo.toml b/Cargo.toml index d8744b6..0df4344 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ repldb = ["database"] database = ["dep:sea-orm", "dep:sea-query", "dep:migration", "dep:entity"] replspace = [] fun-stuff = ["dep:chrono", "dep:chrono-tz"] -verify_connections = ["dep:hyper", "dep:hyper-tls"] +verify_connections = ["dep:hyper", "dep:hyper-tls", "dep:hyper-util", "dep:http-body-util"] [dependencies] goval = { path = "protobuf", package = "protobuf" } @@ -54,6 +54,8 @@ migration = { path = "migration", optional = true} entity = { path = "entity", optional = true} sea-query = { version = "0.28.5", optional = true } pasetors = { version = "0.6.7", default-features = false, features = ["v2"] } -hyper = { version = "0.14.26", features = ["http1", "http2", "client"], optional = true } -hyper-tls = { version = "0.5.0", optional = true } +hyper = { version = "1.1.0", features = ["http1", "http2", "client"], optional = true } +hyper-util = { version = "0.1.2", features = ["client", "client-legacy", "http1", "http2"], optional = true } +hyper-tls = { version = "0.6.0", optional = true } +http-body-util = { version = "0.1.0", optional = true } anyhow = "1.0.71" diff --git a/src/parse_paseto.rs b/src/parse_paseto.rs index c366338..3ce4514 100644 --- a/src/parse_paseto.rs +++ b/src/parse_paseto.rs @@ -41,15 +41,23 @@ fn parse_noverify(input: &str) -> Result<(Vec, bool)> { #[cfg(feature = "verify_connections")] async fn init_keys() -> Result> { + use http_body_util::{BodyExt, Collected}; + use hyper_tls::HttpsConnector; + use hyper_util::client::legacy::{connect::HttpConnector, Client}; + use hyper_util::rt::TokioExecutor; + let key_get = std::env::var("HOMEVAL_PASETO_KEY_URL")?; - let https = hyper_tls::HttpsConnector::new(); - let client = hyper::Client::builder().build::<_, hyper::Body>(https); + let https = HttpsConnector::new(); + let client: Client, Collected<_>> = + Client::builder(TokioExecutor::new()) + .build::, Collected>(https); + + let mut _body = client.get(hyper::Uri::try_from(key_get)?).await?; - let _body = client.get(hyper::Uri::try_from(key_get)?).await?; - let body = hyper::body::to_bytes(_body).await?.to_vec(); + let body = _body.body_mut().collect().await?.to_bytes(); - Ok(serde_json::from_slice(body.as_slice())?) + Ok(serde_json::from_slice(&body)?) } #[cfg(feature = "verify_connections")] From ae7415e6bc5b28f8ff35f368c1c4f9b3b2bd1344 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 22 Jan 2024 14:42:59 -0800 Subject: [PATCH 034/103] ci(clippy): Enable clippy ci for all pushs & prs --- .github/workflows/clippy.yml | 47 ++++++++++++++++++++++++++++++++++++ rust-toolchain.toml | 2 +- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/clippy.yml diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml new file mode 100644 index 0000000..a947063 --- /dev/null +++ b/.github/workflows/clippy.yml @@ -0,0 +1,47 @@ +{ + "on": { "push": {}, "pull_request": {} }, + "name": "Clippy", + "permissions": { "security-events": "write" }, + "jobs": + { + "enforce-clippy": + { + "runs-on": "ubuntu-latest", + "steps": + [ + { + "name": "Checkout", + "uses": "actions/checkout@v4", + }, + { + "name": "Install Rust", + "uses": "dtolnay/rust-toolchain@master", + "with": + { + "components": "clippy", + "toolchain": "nightly-2024-01-01", + }, + }, + { + "name": "Cache", + "uses": "Swatinem/rust-cache@v2", + }, + { + "name": "Install tools", + "run": "cargo install clippy-sarif sarif-fmt", + }, + { + "name": "Generate SARIF", + "run": + "cargo clippy --all-features --message-format=json | + clippy-sarif | tee results.sarif | sarif-fmt", + }, + { + "name": "Upload SARIF file", + "uses": "github/codeql-action/upload-sarif@v2", + "with": { "sarif_file": "results.sarif" }, + }, + ], + }, + }, +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 5d56faf..4757914 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "nightly" +channel = "nightly-2024-01-01" From e236303008c073cbdca501835182407300190976 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 22 Jan 2024 14:44:34 -0800 Subject: [PATCH 035/103] ci(clippy): Fix config --- .github/workflows/clippy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index a947063..5bdc92a 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -1,5 +1,5 @@ { - "on": { "push": {}, "pull_request": {} }, + "on": { "push": { "branches": "main" }, "pull_request": {} }, "name": "Clippy", "permissions": { "security-events": "write" }, "jobs": From 5d8433f884dbb50a460dee12ed249b8a2d757b92 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 22 Jan 2024 16:42:52 -0800 Subject: [PATCH 036/103] ci(clippy): Make sure to install mold linker --- .github/workflows/clippy.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 5bdc92a..bfe33cb 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -22,6 +22,10 @@ "toolchain": "nightly-2024-01-01", }, }, + { + "name": "Install Mold Linker", + "uses": "rui314/setup-mold@v1", + }, { "name": "Cache", "uses": "Swatinem/rust-cache@v2", From 90cca0fdf0c4a5f5c9a218d2a79fe6ff60584430 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 22 Jan 2024 16:46:06 -0800 Subject: [PATCH 037/103] ci(clippy): Attempt for better error message --- .github/workflows/clippy.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index bfe33cb..2994040 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -34,6 +34,10 @@ "name": "Install tools", "run": "cargo install clippy-sarif sarif-fmt", }, + { + "name": "Test build", + "run": "cargo build --all-features", + }, { "name": "Generate SARIF", "run": From c5ae268b0ade2d9d7e6fd5202d4f6e3610935555 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 22 Jan 2024 16:50:19 -0800 Subject: [PATCH 038/103] ci(clippy): Install cranelift codegen and update rust --- .github/workflows/clippy.yml | 8 ++------ rust-toolchain.toml | 2 +- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 2994040..0bffd2b 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -18,8 +18,8 @@ "uses": "dtolnay/rust-toolchain@master", "with": { - "components": "clippy", - "toolchain": "nightly-2024-01-01", + "components": "clippy,rustc-codegen-cranelift", + "toolchain": "nightly-2024-01-22", }, }, { @@ -34,10 +34,6 @@ "name": "Install tools", "run": "cargo install clippy-sarif sarif-fmt", }, - { - "name": "Test build", - "run": "cargo build --all-features", - }, { "name": "Generate SARIF", "run": diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 4757914..525e084 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "nightly-2024-01-01" +channel = "nightly-2024-01-22" From 166df8142cf5029bbb42be71f66ed3d5fc3ba324 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 22 Jan 2024 16:54:33 -0800 Subject: [PATCH 039/103] ci(clippy): Install protoc --- .github/workflows/clippy.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/clippy.yml b/.github/workflows/clippy.yml index 0bffd2b..5d8920f 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/clippy.yml @@ -26,6 +26,10 @@ "name": "Install Mold Linker", "uses": "rui314/setup-mold@v1", }, + { + "name": "Install Protoc", + "uses": "arduino/setup-protoc@v2", + }, { "name": "Cache", "uses": "Swatinem/rust-cache@v2", From 937c8ca55af3aa8593bdaa260712d11f2a7066c4 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 22 Jan 2024 18:11:30 -0800 Subject: [PATCH 040/103] ci(build): Add build action --- .github/workflows/{clippy.yml => ci.yml} | 49 +++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) rename .github/workflows/{clippy.yml => ci.yml} (52%) diff --git a/.github/workflows/clippy.yml b/.github/workflows/ci.yml similarity index 52% rename from .github/workflows/clippy.yml rename to .github/workflows/ci.yml index 5d8920f..5d73b12 100644 --- a/.github/workflows/clippy.yml +++ b/.github/workflows/ci.yml @@ -1,11 +1,12 @@ { "on": { "push": { "branches": "main" }, "pull_request": {} }, - "name": "Clippy", + "name": "CI", "permissions": { "security-events": "write" }, "jobs": { "enforce-clippy": { + "name": "Upload Clippy Lints", "runs-on": "ubuntu-latest", "steps": [ @@ -51,5 +52,51 @@ }, ], }, + "build": + { + "name": "Build", + "runs-on": "ubuntu-latest", + "steps": + [ + { + "name": "Checkout", + "uses": "actions/checkout@v4", + }, + { + "name": "Install Rust", + "uses": "dtolnay/rust-toolchain@master", + "with": + { + "components": "clippy", + "toolchain": "nightly-2024-01-22", + }, + }, + { + "name": "Install Mold Linker", + "uses": "rui314/setup-mold@v1", + }, + { + "name": "Install Protoc", + "uses": "arduino/setup-protoc@v2", + }, + { + "name": "Cache", + "uses": "Swatinem/rust-cache@v2", + }, + { + "name": "Build Homeval", + "run": "cargo build --release --all-features", + }, + { + "name": "Upload Artifact", + "uses": "actions/upload-artifact@v4", + "with": + { + "path": "target/release/homeval", + "name": "homeval-linux-x86", + }, + }, + ], + }, }, } From c21e4c119c381016bc14e10ff9592cbd6c50f75f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 28 Jan 2024 05:28:04 +0000 Subject: [PATCH 041/103] build(deps): bump axum from 0.6.20 to 0.7.4 Bumps [axum](https://github.com/tokio-rs/axum) from 0.6.20 to 0.7.4. - [Release notes](https://github.com/tokio-rs/axum/releases) - [Changelog](https://github.com/tokio-rs/axum/blob/main/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/axum/compare/axum-v0.6.20...axum-v0.7.4) --- updated-dependencies: - dependency-name: axum dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 104 +++++++++++++++++------------------------------------ Cargo.toml | 2 +- 2 files changed, 34 insertions(+), 72 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a073fc..9edc244 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -144,19 +144,20 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.6.20" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +checksum = "1236b4b292f6c4d6dc34604bb5120d85c3fe1d1aa596bd5cc52ca054d13e7b9e" dependencies = [ "async-trait", "axum-core", "base64 0.21.7", - "bitflags 1.3.2", "bytes", "futures-util", - "http 0.2.11", - "http-body 0.4.6", - "hyper 0.14.28", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", "itoa", "matchit", "memchr", @@ -175,23 +176,28 @@ dependencies = [ "tower", "tower-layer", "tower-service", + "tracing", ] [[package]] name = "axum-core" -version = "0.3.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" dependencies = [ "async-trait", "bytes", "futures-util", - "http 0.2.11", - "http-body 0.4.6", + "http", + "http-body", + "http-body-util", "mime", + "pin-project-lite", "rustversion", + "sync_wrapper", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -912,7 +918,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 1.0.0", + "http", "indexmap 2.1.0", "slab", "tokio", @@ -1022,7 +1028,7 @@ dependencies = [ "futures-channel", "futures-util", "http-body-util", - "hyper 1.1.0", + "hyper", "hyper-tls", "hyper-util", "log", @@ -1041,17 +1047,6 @@ dependencies = [ "toml", ] -[[package]] -name = "http" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http" version = "1.0.0" @@ -1063,17 +1058,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.11", - "pin-project-lite", -] - [[package]] name = "http-body" version = "1.0.0" @@ -1081,7 +1065,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "http 1.0.0", + "http", ] [[package]] @@ -1092,8 +1076,8 @@ checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" dependencies = [ "bytes", "futures-util", - "http 1.0.0", - "http-body 1.0.0", + "http", + "http-body", "pin-project-lite", ] @@ -1115,29 +1099,6 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "hyper" -version = "0.14.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http 0.2.11", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "hyper" version = "1.1.0" @@ -1148,9 +1109,10 @@ dependencies = [ "futures-channel", "futures-util", "h2", - "http 1.0.0", - "http-body 1.0.0", + "http", + "http-body", "httparse", + "httpdate", "itoa", "pin-project-lite", "tokio", @@ -1165,7 +1127,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.1.0", + "hyper", "hyper-util", "native-tls", "tokio", @@ -1182,9 +1144,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.0.0", - "http-body 1.0.0", - "hyper 1.1.0", + "http", + "http-body", + "hyper", "pin-project-lite", "socket2", "tokio", @@ -3261,9 +3223,9 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" dependencies = [ "futures-util", "log", @@ -3402,14 +3364,14 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" -version = "0.20.1" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" dependencies = [ "byteorder", "bytes", "data-encoding", - "http 0.2.11", + "http", "httparse", "log", "rand 0.8.5", diff --git a/Cargo.toml b/Cargo.toml index 0df4344..8e89b94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ serde = { version = "1.0.162", features = ["derive"] } tokio = {version="1.26.0", features = ["full"]} base64 = "0.21.0" futures = "0.3.28" -axum = { version = "0.6.18", features = ["ws"] } +axum = { version = "0.7.4", features = ["ws"] } cpu-time = "1.0.0" deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } toml = "0.8.8" From 6279a1b6210dbd610c8d429693ffac7115bdf9fd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 28 Jan 2024 05:28:21 +0000 Subject: [PATCH 042/103] build(deps): bump notify-debouncer-full from 0.2.0 to 0.3.1 Bumps [notify-debouncer-full](https://github.com/notify-rs/notify) from 0.2.0 to 0.3.1. - [Release notes](https://github.com/notify-rs/notify/releases) - [Changelog](https://github.com/notify-rs/notify/blob/main/CHANGELOG.md) - [Commits](https://github.com/notify-rs/notify/compare/file-id-0.2.0...debouncer-full-0.3.1) --- updated-dependencies: - dependency-name: notify-debouncer-full dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 11 ++++++----- services/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a073fc..03b6404 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -674,11 +674,11 @@ checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" [[package]] name = "file-id" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13be71e6ca82e91bc0cb862bebaac0b2d1924a5a1d970c822b2f98b63fda8c3" +checksum = "6584280525fb2059cba3db2c04abf947a1a29a45ddae89f3870f8281704fafc9" dependencies = [ - "winapi-util", + "windows-sys 0.48.0", ] [[package]] @@ -1547,11 +1547,12 @@ dependencies = [ [[package]] name = "notify-debouncer-full" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416969970ec751a5d702a88c6cd19ac1332abe997fce43f96db0418550426241" +checksum = "49f5dab59c348b9b50cf7f261960a20e389feb2713636399cd9082cd4b536154" dependencies = [ "file-id", + "log", "notify", "parking_lot 0.12.1", "walkdir", diff --git a/services/Cargo.toml b/services/Cargo.toml index 97a9152..3429474 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -13,7 +13,7 @@ deadqueue = { version = "0.2.4", default-features = false, features = ["unlimite futures-util = "0.3.28" goval = { package = "protobuf", path = "../protobuf"} log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } -notify-debouncer-full = { version = "0.2.0", default-features = false } +notify-debouncer-full = { version = "0.3.1", default-features = false } portable-pty = "0.8.1" prost = "0.12.3" prost-types = "0.12.3" From 3700792ba3223ef98f6c9a7154a59fe5fdb6fc15 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 28 Jan 2024 05:28:31 +0000 Subject: [PATCH 043/103] build(deps): bump h2 from 0.4.1 to 0.4.2 Bumps [h2](https://github.com/hyperium/h2) from 0.4.1 to 0.4.2. - [Release notes](https://github.com/hyperium/h2/releases) - [Changelog](https://github.com/hyperium/h2/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/h2/compare/v0.4.1...v0.4.2) --- updated-dependencies: - dependency-name: h2 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a073fc..ed8cdf7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -903,9 +903,9 @@ checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "h2" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "991910e35c615d8cab86b5ab04be67e6ad24d2bf5f4f11fdbbed26da999bbeab" +checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943" dependencies = [ "bytes", "fnv", From 462491819131c61d19241df2231c5d7b83302f5c Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 27 Jan 2024 22:06:14 -0800 Subject: [PATCH 044/103] build(deps): Finish axum update --- src/goval_server.rs | 25 ++++++++++++++----------- src/repldb_server.rs | 21 ++++++++------------- src/replspace_server.rs | 11 ++++++++--- 3 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/goval_server.rs b/src/goval_server.rs index a5b2296..ef205ac 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -37,9 +37,10 @@ struct AppState { static DEFAULT_REPLY: &str = "(づ ◕‿◕ )づ Hello there"; pub async fn start_server() -> Result<()> { - let addr = std::env::args() + let addr: SocketAddr = std::env::args() .nth(1) - .unwrap_or_else(|| "127.0.0.1:8080".to_string()); + .unwrap_or_else(|| "127.0.0.1:8080".to_string()) + .parse()?; let (tx, mut rx) = mpsc::unbounded_channel::(); @@ -50,17 +51,19 @@ pub async fn start_server() -> Result<()> { info!("Goval server listening on: {}", addr); tokio::spawn(async move { - axum::Server::bind(&addr.parse().unwrap()) - .serve(app.into_make_service_with_connect_info::()) - .await - .unwrap() - }); + let max_channel = Mutex::new(0); - let max_channel = Mutex::new(0); + while let Some(message) = rx.recv().await { + handle_message(message, &SESSION_MAP, &max_channel).await; + } + }); - while let Some(message) = rx.recv().await { - handle_message(message, &SESSION_MAP, &max_channel).await; - } + let listener = tokio::net::TcpListener::bind(&addr).await?; + axum::serve( + listener, + app.into_make_service_with_connect_info::(), + ) + .await?; Ok(()) } diff --git a/src/repldb_server.rs b/src/repldb_server.rs index 977364a..80dca2b 100644 --- a/src/repldb_server.rs +++ b/src/repldb_server.rs @@ -10,7 +10,7 @@ use log::{as_error, error, info, warn}; use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; use sea_query::OnConflict; use serde::Deserialize; -use std::{collections::HashMap, net::TcpListener}; +use std::{collections::HashMap, net::SocketAddr}; pub async fn start_server() -> Result<()> { if crate::DATABASE.get().is_none() { @@ -24,10 +24,13 @@ pub async fn start_server() -> Result<()> { .route("/:key", get(get_value)) .route("/:key", delete(delete_value)); - let listener = TcpListener::bind("127.0.0.1:0")?; + let listener = if let Ok(addr) = std::env::var("HOMEVAL_REPLDB_ADDR") { + tokio::net::TcpListener::bind(addr.parse::()?).await? + } else { + tokio::net::TcpListener::bind("127.0.0.1:0").await? + }; - let port = listener.local_addr()?.port(); - let host = format!("127.0.0.1:{}", port); + let host = format!("127.0.0.1:{}", listener.local_addr()?); info!("ReplDB server listening on: {}", host); crate::CHILD_PROCS_ENV_BASE @@ -35,15 +38,7 @@ pub async fn start_server() -> Result<()> { .await .insert("REPLIT_DB_URL".to_string(), host); - let builder; - - if let Ok(addr) = std::env::var("HOMEVAL_REPLDB_ADDR") { - builder = axum::Server::bind(&addr.parse()?) - } else { - builder = axum::Server::from_tcp(listener)? - } - - builder.serve(app.into_make_service()).await?; + axum::serve(listener, app.into_make_service()).await?; Ok(()) } diff --git a/src/replspace_server.rs b/src/replspace_server.rs index 37b96ef..9f8b534 100644 --- a/src/replspace_server.rs +++ b/src/replspace_server.rs @@ -1,3 +1,5 @@ +use std::net::SocketAddr; + use anyhow::Result; use axum::{ extract::Query, @@ -18,9 +20,12 @@ pub async fn start_server() -> Result<()> { .route("/files/open", post(open_file)) .route("/github/token", get(get_gh_token)); - axum::Server::bind(&"127.0.0.1:8283".parse().unwrap()) - .serve(app.into_make_service()) - .await?; + let listener = tokio::net::TcpListener::bind(&"127.0.0.1:8283".parse::()?) + .await + .unwrap(); + axum::serve(listener, app.into_make_service()) + .await + .unwrap(); Ok(()) } From 4d1ba8adc8ad275e7c8e2f1d2c73ef6610d8a710 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 27 Jan 2024 22:56:43 -0800 Subject: [PATCH 045/103] build(deps): bump all sea-orm package versions closes #73 closes #75 closes #79 --- .github/dependabot.yml | 12 - Cargo.lock | 937 ++++++++++++++++++++++++++--------------- Cargo.toml | 6 +- entity/Cargo.toml | 2 +- migration/Cargo.toml | 2 +- 5 files changed, 596 insertions(+), 363 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index ad268ff..90052cd 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -12,15 +12,3 @@ updates: labels: - "cargo" - "dependencies" - - package-ecosystem: "npm" - directory: "/" - schedule: - interval: "weekly" - assignees: - - "PotentialStyx" - commit-message: - prefix: "build(deps):" - include: "scope" - labels: - - "npm" - - "dependencies" diff --git a/Cargo.lock b/Cargo.lock index 6a3537c..97509ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" - [[package]] name = "addr2line" version = "0.21.0" @@ -41,6 +35,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if", + "getrandom 0.2.12", "once_cell", "version_check", "zerocopy", @@ -82,6 +77,54 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "anyhow" version = "1.0.79" @@ -129,13 +172,23 @@ dependencies = [ [[package]] name = "atoi" -version = "1.0.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" dependencies = [ "num-traits", ] +[[package]] +name = "atomic-write-file" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" +dependencies = [ + "nix 0.27.1", + "rand 0.8.5", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -215,19 +268,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "bae" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b8de67cc41132507eeece2584804efcb15f85ba516e34c944b7667f480397a" -dependencies = [ - "heck 0.3.3", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "base64" version = "0.12.3" @@ -236,15 +276,15 @@ checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" [[package]] name = "base64" -version = "0.13.1" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "base64" -version = "0.21.7" +name = "base64ct" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] name = "bigdecimal" @@ -268,6 +308,9 @@ name = "bitflags" version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +dependencies = [ + "serde", +] [[package]] name = "bitvec" @@ -377,16 +420,15 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "chrono" -version = "0.4.29" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d87d9d13be47a5b7c3907137f1290b0459a7f80efb26be8c52afb11963bccb02" +checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", - "time 0.1.45", - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] @@ -413,39 +455,55 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.25" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ - "bitflags 1.3.2", + "clap_builder", "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +dependencies = [ + "anstream", + "anstyle", "clap_lex", - "indexmap 1.9.3", - "once_cell", - "textwrap", + "strsim", ] [[package]] name = "clap_derive" -version = "3.2.25" +version = "4.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" dependencies = [ - "heck 0.4.1", - "proc-macro-error", + "heck", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", ] [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "core-foundation" @@ -482,6 +540,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + [[package]] name = "crc32fast" version = "1.3.2" @@ -547,6 +620,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.11" @@ -557,6 +641,17 @@ dependencies = [ "serde", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "digest" version = "0.10.7" @@ -564,30 +659,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] -[[package]] -name = "dirs" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "dotenvy" version = "0.15.7" @@ -614,6 +690,9 @@ name = "either" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +dependencies = [ + "serde", +] [[package]] name = "entity" @@ -660,6 +739,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -706,7 +796,7 @@ checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall", "windows-sys 0.52.0", ] @@ -722,6 +812,17 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + [[package]] name = "fnv" version = "1.0.7" @@ -811,13 +912,13 @@ dependencies = [ [[package]] name = "futures-intrusive" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" dependencies = [ "futures-core", "lock_api", - "parking_lot 0.11.2", + "parking_lot", ] [[package]] @@ -907,6 +1008,12 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "h2" version = "0.4.2" @@ -919,7 +1026,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.1.0", + "indexmap", "slab", "tokio", "tokio-util", @@ -954,15 +1061,6 @@ dependencies = [ "hashbrown 0.14.3", ] -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "heck" version = "0.4.1" @@ -1190,22 +1288,23 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.3" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ - "autocfg", - "hashbrown 0.12.3", + "equivalent", + "hashbrown 0.14.3", ] [[package]] -name = "indexmap" -version = "2.1.0" +name = "inherent" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947" dependencies = [ - "equivalent", - "hashbrown 0.14.3", + "proc-macro2", + "quote", + "syn 2.0.48", ] [[package]] @@ -1228,15 +1327,6 @@ dependencies = [ "libc", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - [[package]] name = "ioctl-rs" version = "0.1.6" @@ -1315,6 +1405,9 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] [[package]] name = "libc" @@ -1323,14 +1416,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] -name = "libredox" -version = "0.0.1" +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" dependencies = [ - "bitflags 2.4.1", - "libc", - "redox_syscall 0.4.1", + "cc", + "pkg-config", + "vcpkg", ] [[package]] @@ -1478,6 +1577,17 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "libc", +] + [[package]] name = "nom" version = "7.1.3" @@ -1516,7 +1626,7 @@ dependencies = [ "file-id", "log", "notify", - "parking_lot 0.12.1", + "parking_lot", "walkdir", ] @@ -1531,6 +1641,23 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -1541,6 +1668,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.17" @@ -1548,6 +1686,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -1619,6 +1758,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "ordered-float" +version = "3.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" +dependencies = [ + "num-traits", +] + [[package]] name = "orion" version = "0.17.6" @@ -1630,44 +1778,28 @@ dependencies = [ "zeroize", ] -[[package]] -name = "os_str_bytes" -version = "6.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" - [[package]] name = "ouroboros" -version = "0.15.6" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1358bd1558bd2a083fed428ffeda486fbfb323e698cdda7794259d592ca72db" +checksum = "e2ba07320d39dfea882faa70554b4bd342a5f273ed59ba7c1c6b4c840492c954" dependencies = [ "aliasable", "ouroboros_macro", + "static_assertions", ] [[package]] name = "ouroboros_macro" -version = "0.15.6" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7" +checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" dependencies = [ - "Inflector", + "heck", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", -] - -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", + "syn 2.0.48", ] [[package]] @@ -1677,21 +1809,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.9", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -1702,7 +1820,7 @@ checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.4.1", + "redox_syscall", "smallvec", "windows-targets 0.48.5", ] @@ -1736,6 +1854,15 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1749,7 +1876,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.1.0", + "indexmap", ] [[package]] @@ -1823,11 +1950,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "pkg-config" -version = "0.3.28" +name = "pkcs1" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" - +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" + [[package]] name = "portable-pty" version = "0.8.1" @@ -1841,7 +1989,7 @@ dependencies = [ "lazy_static", "libc", "log", - "nix", + "nix 0.25.1", "serial", "shared_library", "shell-words", @@ -1930,7 +2078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", - "heck 0.4.1", + "heck", "itertools 0.10.5", "log", "multimap", @@ -2082,15 +2230,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -2100,17 +2239,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_users" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" -dependencies = [ - "getrandom 0.2.12", - "libredox", - "thiserror", -] - [[package]] name = "regex" version = "1.10.2" @@ -2164,21 +2292,6 @@ dependencies = [ "bytecheck", ] -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin 0.5.2", - "untrusted 0.7.1", - "web-sys", - "winapi", -] - [[package]] name = "ring" version = "0.17.7" @@ -2189,7 +2302,7 @@ dependencies = [ "getrandom 0.2.12", "libc", "spin 0.9.8", - "untrusted 0.9.0", + "untrusted", "windows-sys 0.48.0", ] @@ -2232,6 +2345,26 @@ dependencies = [ "str_indices", ] +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rust_decimal" version = "1.33.1" @@ -2269,14 +2402,13 @@ dependencies = [ [[package]] name = "rustls" -version = "0.20.9" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ - "log", - "ring 0.16.20", + "ring", + "rustls-webpki", "sct", - "webpki", ] [[package]] @@ -2288,6 +2420,16 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "rustversion" version = "1.0.14" @@ -2330,15 +2472,28 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.7", - "untrusted 0.9.0", + "ring", + "untrusted", +] + +[[package]] +name = "sea-bae" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd3534a9978d0aa7edd2808dc1f8f31c4d0ecd31ddf71d997b3c98e9f3c9114" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.48", ] [[package]] name = "sea-orm" -version = "0.11.3" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fade86e8d41fd1a4721f84cb834f4ca2783f973cc30e6212b7fafc134f169214" +checksum = "0cbf88748872fa54192476d6d49d0775e208566a72656e267e45f6980b926c8d" dependencies = [ "async-stream", "async-trait", @@ -2351,12 +2506,12 @@ dependencies = [ "sea-orm-macros", "sea-query", "sea-query-binder", - "sea-strum", "serde", "serde_json", "sqlx", + "strum", "thiserror", - "time 0.3.31", + "time", "tracing", "url", "uuid", @@ -2364,13 +2519,14 @@ dependencies = [ [[package]] name = "sea-orm-cli" -version = "0.11.3" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbf34a2caf70c2e3be9bb1e674e9540f6dfd7c8f40f6f05daf3b9740e476005" +checksum = "9f17eb697616be2f3e4ea3b468a44cfb6848750dec522fdef4caa44bf5a02beb" dependencies = [ "chrono", "clap", "dotenvy", + "glob", "regex", "sea-schema", "tracing", @@ -2380,22 +2536,23 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "0.11.3" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28936f26d62234ff0be16f80115dbdeb3237fe9c25cf18fbcd1e3b3592360f20" +checksum = "e0dbc880d47aa53c6a572e39c99402c7fad59b50766e51e0b0fc1306510b0555" dependencies = [ - "bae", - "heck 0.3.3", + "heck", "proc-macro2", "quote", - "syn 1.0.109", + "sea-bae", + "syn 2.0.48", + "unicode-ident", ] [[package]] name = "sea-orm-migration" -version = "0.11.3" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "278d3adfd0832b6ffc17d3cfbc574d3695a5c1b38814e0bc8ac238d33f3d87cf" +checksum = "e42807e13d38edd4cc1f9cbb370df898d43a9a143f6161dcdb8424a6de002def" dependencies = [ "async-trait", "clap", @@ -2410,24 +2567,27 @@ dependencies = [ [[package]] name = "sea-query" -version = "0.28.5" +version = "0.30.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbab99b8cd878ab7786157b7eb8df96333a6807cc6e45e8888c85b51534b401a" +checksum = "4166a1e072292d46dc91f31617c2a1cdaf55a8be4b5c9f4bf2ba248e3ac4999b" dependencies = [ "bigdecimal", "chrono", + "derivative", + "inherent", + "ordered-float", "rust_decimal", "sea-query-derive", "serde_json", - "time 0.3.31", + "time", "uuid", ] [[package]] name = "sea-query-binder" -version = "0.3.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cea85029985b40dfbf18318d85fe985c04db7c1b4e5e8e0a0a0cdff5f1e30f9" +checksum = "36bbb68df92e820e4d5aeb17b4acd5cc8b5d18b2c36a4dd6f4626aabfa7ab1b9" dependencies = [ "bigdecimal", "chrono", @@ -2435,28 +2595,28 @@ dependencies = [ "sea-query", "serde_json", "sqlx", - "time 0.3.31", + "time", "uuid", ] [[package]] name = "sea-query-derive" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63f62030c60f3a691f5fe251713b4e220b306e50a71e1d6f9cce1f24bb781978" +checksum = "25a82fcb49253abcb45cdcb2adf92956060ec0928635eb21b4f7a6d8f25ab0bc" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.48", "thiserror", ] [[package]] name = "sea-schema" -version = "0.11.0" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeb2940bb5a10bc6cd05b450ce6cd3993e27fddd7eface2becb97fc5af3a040e" +checksum = "30d148608012d25222442d1ebbfafd1228dbc5221baf4ec35596494e27a2394e" dependencies = [ "futures", "sea-query", @@ -2465,35 +2625,13 @@ dependencies = [ [[package]] name = "sea-schema-derive" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56821b7076f5096b8f726e2791ad255a99c82498e08ec477a65a96c461ff1927" -dependencies = [ - "heck 0.3.3", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "sea-strum" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391d06a6007842cfe79ac6f7f53911b76dfd69fc9a6769f1cf6569d12ce20e1b" -dependencies = [ - "sea-strum_macros", -] - -[[package]] -name = "sea-strum_macros" -version = "0.23.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69b4397b825df6ccf1e98bcdabef3bbcfc47ff5853983467850eeab878384f21" +checksum = "c6f686050f76bffc4f635cda8aea6df5548666b830b52387e8bc7de11056d11e" dependencies = [ - "heck 0.3.3", + "heck", "proc-macro2", "quote", - "rustversion", "syn 1.0.109", ] @@ -2717,6 +2855,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + [[package]] name = "simdutf8" version = "0.1.4" @@ -2771,6 +2919,19 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] [[package]] name = "sqlformat" @@ -2785,102 +2946,229 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.6.3" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" +checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" dependencies = [ "sqlx-core", "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", ] [[package]] name = "sqlx-core" -version = "0.6.3" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" +checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" dependencies = [ - "ahash 0.7.7", + "ahash 0.8.7", "atoi", - "base64 0.13.1", "bigdecimal", - "bitflags 1.3.2", "byteorder", "bytes", "chrono", + "crc", "crossbeam-queue", - "dirs", "dotenvy", "either", "event-listener", "futures-channel", "futures-core", "futures-intrusive", + "futures-io", "futures-util", "hashlink", "hex", - "hkdf", - "hmac", - "indexmap 1.9.3", - "itoa", - "libc", + "indexmap", "log", - "md-5", "memchr", - "num-bigint", "once_cell", "paste", "percent-encoding", - "rand 0.8.5", "rust_decimal", "rustls", "rustls-pemfile", "serde", "serde_json", - "sha1", "sha2", "smallvec", "sqlformat", - "sqlx-rt", - "stringprep", "thiserror", - "time 0.3.31", + "time", + "tokio", "tokio-stream", + "tracing", "url", "uuid", "webpki-roots", - "whoami", ] [[package]] name = "sqlx-macros" -version = "0.6.3" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" +checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" dependencies = [ + "atomic-write-file", "dotenvy", "either", - "heck 0.4.1", + "heck", + "hex", "once_cell", "proc-macro2", "quote", + "serde", "serde_json", + "sha2", "sqlx-core", - "sqlx-rt", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", "syn 1.0.109", + "tempfile", + "tokio", "url", ] [[package]] -name = "sqlx-rt" -version = "0.6.3" +name = "sqlx-mysql" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" +checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" dependencies = [ + "atoi", + "base64 0.21.7", + "bigdecimal", + "bitflags 2.4.1", + "byteorder", + "bytes", + "chrono", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", "once_cell", - "tokio", - "tokio-rustls", + "percent-encoding", + "rand 0.8.5", + "rsa", + "rust_decimal", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "time", + "tracing", + "uuid", + "whoami", ] +[[package]] +name = "sqlx-postgres" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" +dependencies = [ + "atoi", + "base64 0.21.7", + "bigdecimal", + "bitflags 2.4.1", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "num-bigint", + "once_cell", + "rand 0.8.5", + "rust_decimal", + "serde", + "serde_json", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" +dependencies = [ + "atoi", + "chrono", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "time", + "tracing", + "url", + "urlencoding", + "uuid", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "str_indices" version = "0.4.3" @@ -2898,6 +3186,18 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + [[package]] name = "subtle" version = "2.5.0" @@ -3036,7 +3336,7 @@ checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" dependencies = [ "cfg-if", "fastrand", - "redox_syscall 0.4.1", + "redox_syscall", "rustix", "windows-sys 0.52.0", ] @@ -3069,12 +3369,6 @@ dependencies = [ "rand 0.7.3", ] -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - [[package]] name = "thiserror" version = "1.0.56" @@ -3105,17 +3399,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - [[package]] name = "time" version = "0.3.31" @@ -3171,7 +3454,7 @@ dependencies = [ "libc", "mio", "num_cpus", - "parking_lot 0.12.1", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", @@ -3200,17 +3483,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" -dependencies = [ - "rustls", - "tokio", - "webpki", -] - [[package]] name = "tokio-stream" version = "0.1.14" @@ -3275,7 +3547,7 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" dependencies = [ - "indexmap 2.1.0", + "indexmap", "serde", "serde_spanned", "toml_datetime", @@ -3421,12 +3693,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "untrusted" version = "0.9.0" @@ -3444,12 +3710,24 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "uuid" version = "1.6.1" @@ -3532,12 +3810,6 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3598,34 +3870,11 @@ version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" -[[package]] -name = "web-sys" -version = "0.3.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" -dependencies = [ - "ring 0.17.7", - "untrusted 0.9.0", -] - [[package]] name = "webpki-roots" -version = "0.22.6" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki", -] +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "which" @@ -3644,10 +3893,6 @@ name = "whoami" version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" -dependencies = [ - "wasm-bindgen", - "web-sys", -] [[package]] name = "winapi" diff --git a/Cargo.toml b/Cargo.toml index 8e89b94..6fd0f89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,14 +45,14 @@ toml = "0.8.8" textnonce = "1.0.0" -chrono = { version = "0.4.26", default-features = false, features = ["time", "std", "libc", "clock"], optional = true } +chrono = { version = "0.4.33", default-features = false, features = ["std", "libc", "clock"], optional = true } chrono-tz = { version = "0.8.2", optional = true } -sea-orm = { version = "0.11.3", features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros", "postgres-array" ], optional = true } +sea-orm = { version = "0.12.2", features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros", "postgres-array" ], optional = true } migration = { path = "migration", optional = true} entity = { path = "entity", optional = true} -sea-query = { version = "0.28.5", optional = true } +sea-query = { version = "0.30.7", optional = true } pasetors = { version = "0.6.7", default-features = false, features = ["v2"] } hyper = { version = "1.1.0", features = ["http1", "http2", "client"], optional = true } hyper-util = { version = "0.1.2", features = ["client", "client-legacy", "http1", "http2"], optional = true } diff --git a/entity/Cargo.toml b/entity/Cargo.toml index bc69b57..204e754 100644 --- a/entity/Cargo.toml +++ b/entity/Cargo.toml @@ -9,5 +9,5 @@ path = "src/mod.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -sea-orm = "0.11.3" +sea-orm = "0.12.2" serde = "1.0.162" diff --git a/migration/Cargo.toml b/migration/Cargo.toml index df1da56..946718f 100644 --- a/migration/Cargo.toml +++ b/migration/Cargo.toml @@ -13,7 +13,7 @@ tokio = { version = "1.28.2", features = ["full"]} # async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] -version = "0.11.0" +version = "0.12.12" features = [ # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI. # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime. From 6bb5625984f5976e295cbfc18a86608202b5ff5e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 28 Jan 2024 07:02:27 +0000 Subject: [PATCH 046/103] build(deps): bump serde from 1.0.195 to 1.0.196 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.195 to 1.0.196. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.195...v1.0.196) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- entity/Cargo.toml | 2 +- services/Cargo.toml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 97509ed..11b5a6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2666,18 +2666,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 6fd0f89..c5d43e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } prost = "0.12.3" prost-types = "0.12.3" serde_json = "1.0.97" -serde = { version = "1.0.162", features = ["derive"] } +serde = { version = "1.0.196", features = ["derive"] } tokio = {version="1.26.0", features = ["full"]} base64 = "0.21.0" futures = "0.3.28" diff --git a/entity/Cargo.toml b/entity/Cargo.toml index 204e754..400bea9 100644 --- a/entity/Cargo.toml +++ b/entity/Cargo.toml @@ -10,4 +10,4 @@ path = "src/mod.rs" [dependencies] sea-orm = "0.12.2" -serde = "1.0.162" +serde = "1.0.196" diff --git a/services/Cargo.toml b/services/Cargo.toml index 3429474..675211b 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -18,7 +18,7 @@ portable-pty = "0.8.1" prost = "0.12.3" prost-types = "0.12.3" ropey = "1.6.0" -serde = "1.0.164" +serde = "1.0.196" serde_json = "1.0.97" similar = "2.2.1" tokio = "1.28.2" From 53af7331715fccc9cd6cf504c1cf0482faaf2b46 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 28 Jan 2024 07:14:21 +0000 Subject: [PATCH 047/103] build(deps): bump serde_json from 1.0.111 to 1.0.112 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.111 to 1.0.112. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.111...v1.0.112) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- services/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11b5a6f..5c9c3eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2695,9 +2695,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.112" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "4d1bd37ce2324cf3bf85e5a25f96eb4baf0d5aa6eba43e7ae8958870c4ec48ed" dependencies = [ "itoa", "ryu", diff --git a/Cargo.toml b/Cargo.toml index c5d43e5..e2e7b1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ futures-util = "0.3.26" log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } prost = "0.12.3" prost-types = "0.12.3" -serde_json = "1.0.97" +serde_json = "1.0.112" serde = { version = "1.0.196", features = ["derive"] } tokio = {version="1.26.0", features = ["full"]} base64 = "0.21.0" diff --git a/services/Cargo.toml b/services/Cargo.toml index 675211b..9160ba9 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -19,7 +19,7 @@ prost = "0.12.3" prost-types = "0.12.3" ropey = "1.6.0" serde = "1.0.196" -serde_json = "1.0.97" +serde_json = "1.0.112" similar = "2.2.1" tokio = "1.28.2" From 1a715b1c9ed6952a137ece245f0c81b082d76b21 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Fri, 2 Feb 2024 17:56:30 -0800 Subject: [PATCH 048/103] ci(build): Target more oses when building --- .github/workflows/ci.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d73b12..1077823 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,21 @@ "build": { "name": "Build", - "runs-on": "ubuntu-latest", + "strategy": + { + "matrix": + { + "os": + [ + "ubuntu-latest", + "windows-latest", + "macos-13", + "macos-14", + ], + }, + }, + + "runs-on": "${{ matrix.os }}", "steps": [ { @@ -74,6 +88,7 @@ { "name": "Install Mold Linker", "uses": "rui314/setup-mold@v1", + "if": "${{ runner.os == 'Linux'}}", }, { "name": "Install Protoc", @@ -93,7 +108,7 @@ "with": { "path": "target/release/homeval", - "name": "homeval-linux-x86", + "name": "homeval-${{ runner.os }}-${{ runner.arch }}", }, }, ], From 6534842d3b137c031800b21d29079bef253882d4 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:06:40 -0800 Subject: [PATCH 049/103] ci(build,clippy): Update out of date actions --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1077823..6cdcc65 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ }, { "name": "Install Protoc", - "uses": "arduino/setup-protoc@v2", + "uses": "arduino/setup-protoc@v3", }, { "name": "Cache", @@ -47,7 +47,7 @@ }, { "name": "Upload SARIF file", - "uses": "github/codeql-action/upload-sarif@v2", + "uses": "github/codeql-action/upload-sarif@v3", "with": { "sarif_file": "results.sarif" }, }, ], @@ -92,7 +92,7 @@ }, { "name": "Install Protoc", - "uses": "arduino/setup-protoc@v2", + "uses": "arduino/setup-protoc@v3", }, { "name": "Cache", From bf6ae4e5bfd2fbee16dc02400427400dd52cc587 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:09:36 -0800 Subject: [PATCH 050/103] ci(build,clippy): Authenticate protoc install Fixes ratelimit issues --- .github/workflows/ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6cdcc65..8c3ac82 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,10 @@ { "name": "Install Protoc", "uses": "arduino/setup-protoc@v3", + "with": + { + "repo-token": "${{ secrets.GITHUB_TOKEN }}", + }, }, { "name": "Cache", @@ -93,6 +97,10 @@ { "name": "Install Protoc", "uses": "arduino/setup-protoc@v3", + "with": + { + "repo-token": "${{ secrets.GITHUB_TOKEN }}", + }, }, { "name": "Cache", From 66d869112374bc7607bf901975cdbfd7c034c191 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:19:42 -0800 Subject: [PATCH 051/103] ci(build): Fix artifact naming Also makes windows artifact uploading work --- .github/workflows/ci.yml | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8c3ac82..0febeda 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -70,6 +70,25 @@ "macos-13", "macos-14", ], + "include": + [ + { + "os": "windows-latest", + "descriptor": "windows-x86", + }, + { + "os": "ubuntu-latest", + "descriptor": "linux-x86", + }, + { + "os": "macos-13", + "descriptor": "macos-x86", + }, + { + "os": "macos-14", + "descriptor": "macos-arm", + }, + ], }, }, @@ -115,8 +134,8 @@ "uses": "actions/upload-artifact@v4", "with": { - "path": "target/release/homeval", - "name": "homeval-${{ runner.os }}-${{ runner.arch }}", + "path": "${{ runner.os != 'Windows' && 'target/release/homeval' || 'target\\release\\homeval.exe' }}", + "name": "homeval-${{ matrix.descriptor && matrix.descriptor || format('{0}-{1}', runner.os, runner.arch) }}", }, }, ], From ba3b35a6db1119b952afb5dbe7607be3ddbd2bc2 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:24:12 -0800 Subject: [PATCH 052/103] ci(build): Fix windows artifact name --- .github/workflows/ci.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0febeda..d1777c3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,19 +74,19 @@ [ { "os": "windows-latest", - "descriptor": "windows-x86", + "suffix": "windows-x86.exe", }, { "os": "ubuntu-latest", - "descriptor": "linux-x86", + "suffix": "linux-x86", }, { "os": "macos-13", - "descriptor": "macos-x86", + "suffix": "macos-x86", }, { "os": "macos-14", - "descriptor": "macos-arm", + "suffix": "macos-arm", }, ], }, @@ -135,7 +135,7 @@ "with": { "path": "${{ runner.os != 'Windows' && 'target/release/homeval' || 'target\\release\\homeval.exe' }}", - "name": "homeval-${{ matrix.descriptor && matrix.descriptor || format('{0}-{1}', runner.os, runner.arch) }}", + "name": "homeval-${{ matrix.suffix && matrix.suffix || format('{0}-{1}', runner.os, runner.arch) }}", }, }, ], From e7bd26575100d6f21f88a42a6ea5c04324ad1e04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 3 Feb 2024 02:38:55 +0000 Subject: [PATCH 053/103] build(deps): bump serde_json from 1.0.112 to 1.0.113 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.112 to 1.0.113. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.112...v1.0.113) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- services/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c9c3eb..1061a33 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2695,9 +2695,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.112" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d1bd37ce2324cf3bf85e5a25f96eb4baf0d5aa6eba43e7ae8958870c4ec48ed" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa", "ryu", diff --git a/Cargo.toml b/Cargo.toml index e2e7b1f..b5392de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ futures-util = "0.3.26" log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } prost = "0.12.3" prost-types = "0.12.3" -serde_json = "1.0.112" +serde_json = "1.0.113" serde = { version = "1.0.196", features = ["derive"] } tokio = {version="1.26.0", features = ["full"]} base64 = "0.21.0" diff --git a/services/Cargo.toml b/services/Cargo.toml index 9160ba9..9c89f7d 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -19,7 +19,7 @@ prost = "0.12.3" prost-types = "0.12.3" ropey = "1.6.0" serde = "1.0.196" -serde_json = "1.0.112" +serde_json = "1.0.113" similar = "2.2.1" tokio = "1.28.2" From e2d61d0b6403abde3bfb7ff938bd020db169ec42 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 3 Feb 2024 21:49:13 -0800 Subject: [PATCH 054/103] refactor: Switch to tracing for logs --- Cargo.lock | 92 +++++++++++++----------- Cargo.toml | 4 +- services/Cargo.toml | 3 +- services/src/chat.rs | 4 +- services/src/gcsfiles.rs | 8 +-- services/src/git.rs | 11 +-- services/src/lib.rs | 7 +- services/src/ot.rs | 17 +++-- services/src/output.rs | 4 +- services/src/presence.rs | 6 +- services/src/shell.rs | 4 +- services/src/toolchain.rs | 4 +- services/src/types/channel_info.rs | 2 +- services/src/types/fs_watcher.rs | 4 +- services/src/types/proc.rs | 2 +- services/src/types/pty.rs | 8 +-- src/database.rs | 2 +- src/goval_server.rs | 111 +++++++++++++++-------------- src/main.rs | 4 +- src/parse_paseto.rs | 4 +- src/repldb_server.rs | 10 +-- src/replspace_server.rs | 10 +-- 22 files changed, 174 insertions(+), 147 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c9c3eb..e2a5b9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -702,18 +702,6 @@ dependencies = [ "serde", ] -[[package]] -name = "env_logger" -version = "0.10.0" -source = "git+https://github.com/tmccombs/env_logger?rev=a47d1d99#a47d1d99f4bf556dc82e2d1d62f3811c0c4d1171" -dependencies = [ - "humantime", - "is-terminal", - "log", - "regex", - "termcolor", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -1121,7 +1109,6 @@ dependencies = [ "cpu-time", "deadqueue", "entity", - "env_logger", "futures", "futures-channel", "futures-util", @@ -1143,6 +1130,9 @@ dependencies = [ "textnonce", "tokio", "toml", + "tracing", + "tracing-futures", + "tracing-subscriber", ] [[package]] @@ -1191,12 +1181,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "hyper" version = "1.1.0" @@ -1336,17 +1320,6 @@ dependencies = [ "libc", ] -[[package]] -name = "is-terminal" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" -dependencies = [ - "hermit-abi", - "rustix", - "windows-sys 0.52.0", -] - [[package]] name = "itertools" version = "0.10.5" @@ -1630,6 +1603,16 @@ dependencies = [ "walkdir", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-bigint" version = "0.4.4" @@ -1802,6 +1785,12 @@ dependencies = [ "syn 2.0.48", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking_lot" version = "0.12.1" @@ -2786,7 +2775,6 @@ dependencies = [ "crc32fast", "deadqueue", "futures-util", - "log", "notify-debouncer-full", "portable-pty", "prost", @@ -2797,6 +2785,8 @@ dependencies = [ "serde_json", "similar", "tokio", + "tracing", + "tracing-futures", ] [[package]] @@ -3341,15 +3331,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - [[package]] name = "termios" version = "0.2.2" @@ -3612,6 +3593,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", ] [[package]] @@ -3621,12 +3624,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers", + "nu-ansi-term", "once_cell", "regex", "sharded-slab", + "smallvec", "thread_local", "tracing", "tracing-core", + "tracing-log", ] [[package]] @@ -3737,6 +3743,12 @@ dependencies = [ "serde", ] +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "value-bag" version = "1.6.0" diff --git a/Cargo.toml b/Cargo.toml index e2e7b1f..0823b98 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,9 @@ verify_connections = ["dep:hyper", "dep:hyper-tls", "dep:hyper-util", "dep:http- [dependencies] goval = { path = "protobuf", package = "protobuf" } homeval_services = { path = "services", package = "services" } -env_logger = { git = "https://github.com/tmccombs/env_logger", rev = "a47d1d99", features=["kv_unstable"] } +tracing = "0.1.40" +tracing-futures = "0.2.5" +tracing-subscriber = { version = "0.3.18", features = ["tracing-log"]} futures-channel = "0.3.26" futures-util = "0.3.26" log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } diff --git a/services/Cargo.toml b/services/Cargo.toml index 9160ba9..b599689 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -12,7 +12,6 @@ crc32fast = { version = "1.3.2", features = ["nightly"] } deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } futures-util = "0.3.28" goval = { package = "protobuf", path = "../protobuf"} -log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } notify-debouncer-full = { version = "0.3.1", default-features = false } portable-pty = "0.8.1" prost = "0.12.3" @@ -22,6 +21,8 @@ serde = "1.0.196" serde_json = "1.0.112" similar = "2.2.1" tokio = "1.28.2" +tracing = "0.1.40" +tracing-futures = "0.2.5" [lib] name = "services" diff --git a/services/src/chat.rs b/services/src/chat.rs index 728063f..7a72b5b 100644 --- a/services/src/chat.rs +++ b/services/src/chat.rs @@ -7,7 +7,7 @@ use crate::{ClientInfo, IPCMessage, SendSessions}; use super::traits; use anyhow::{format_err, Result}; use async_trait::async_trait; -use log::{as_debug, warn}; +use tracing::warn; impl Chat { pub fn new() -> Chat { @@ -45,7 +45,7 @@ impl traits::Service for Chat { Ok(None) } _ => { - warn!(cmd = as_debug!(message); "Unknown chat command"); + warn!(cmd = ?message, "Unknown chat command"); Ok(None) } } diff --git a/services/src/gcsfiles.rs b/services/src/gcsfiles.rs index 5a17b37..062a941 100644 --- a/services/src/gcsfiles.rs +++ b/services/src/gcsfiles.rs @@ -3,8 +3,8 @@ pub struct GCSFiles {} use super::traits; use anyhow::{format_err, Result}; use async_trait::async_trait; -use log::{as_debug, as_error, debug, warn}; use tokio::{fs, io::AsyncWriteExt}; +use tracing::{debug, warn}; #[async_trait] impl traits::Service for GCSFiles { @@ -58,7 +58,7 @@ impl traits::Service for GCSFiles { Ok(Some(ret)) } goval::command::Body::Read(file) => { - debug!(path = file.path; "File path"); + debug!(path = file.path, "File path"); let contents = match file.path.as_str() { // TODO: Read this from in the db ".env" => vec![], @@ -78,7 +78,7 @@ impl traits::Service for GCSFiles { } _ => match fs::read(&file.path).await { Err(err) => { - warn!(error = as_error!(err); "Error reading file in gcsfiles"); + warn!(error = %err, "Error reading file in gcsfiles"); let ret = goval::Command { body: Some(goval::command::Body::Error(format!( "{}: no such file or directory", @@ -153,7 +153,7 @@ impl traits::Service for GCSFiles { Ok(None) } _ => { - warn!(cmd = as_debug!(message); "Unknown gcsfiles command"); + warn!(cmd = ?message, "Unknown gcsfiles command"); Ok(None) } } diff --git a/services/src/git.rs b/services/src/git.rs index e92fc2b..0d8e273 100644 --- a/services/src/git.rs +++ b/services/src/git.rs @@ -8,8 +8,8 @@ use crate::ReplspaceMessage; use super::traits; use anyhow::{format_err, Result}; use async_trait::async_trait; -use log::{as_debug, warn}; use tokio::sync::mpsc::Sender; +use tracing::warn; #[async_trait] impl traits::Service for Git { @@ -35,7 +35,7 @@ impl traits::Service for Git { } } None => { - warn!(msg = as_debug!(message), nonce = token.nonce; "Missing replspace response callback for github token"); + warn!(msg = ?message, nonce = token.nonce, "Missing replspace response callback for github token"); } } } @@ -47,7 +47,7 @@ impl traits::Service for Git { } } None => { - warn!(msg = as_debug!(message), nonce = close.nonce; "Missing replspace response callback for close file"); + warn!(msg = ?message, nonce = close.nonce, "Missing replspace response callback for close file"); } } } @@ -65,7 +65,10 @@ impl traits::Service for Git { respond: Option>, ) -> Result<()> { if session == 0 { - warn!(msg = as_debug!(msg); "Got replspace message from an unknown session, ignoring"); + warn!( + ?msg, + "Got replspace message from an unknown session, ignoring" + ); return Ok(()); } diff --git a/services/src/lib.rs b/services/src/lib.rs index 7876bd0..4dbba9b 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -15,11 +15,10 @@ mod types; use anyhow::format_err; use anyhow::Result; -use log::as_display; -use log::error; use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; +use tracing::error; pub use types::*; pub struct Channel { @@ -88,7 +87,7 @@ impl Channel { ChannelMessage::Shutdown => match self._inner.shutdown(&self.info).await { Ok(_) => break, Err(err) => { - error!(error = as_display!(err); "Error encountered in Service#shutdown"); + error!(%err, "Error encountered in Service#shutdown"); break; } }, @@ -101,7 +100,7 @@ impl Channel { match result { Ok(_) => {} Err(err) => { - error!(error = as_display!(err); "Error encountered in service") + error!(%err, "Error encountered in service") } } } diff --git a/services/src/ot.rs b/services/src/ot.rs index a84bf45..dc83b23 100644 --- a/services/src/ot.rs +++ b/services/src/ot.rs @@ -18,9 +18,9 @@ use crate::{client::ClientInfo, fs_watcher::FSWatcher, FSEvent, IPCMessage}; use super::traits; use anyhow::{format_err, Result}; use async_trait::async_trait; -use log::{as_debug, debug, error, trace, warn}; use similar::TextDiff; use tokio::fs; +use tracing::{debug, error, trace, warn}; impl OT { pub async fn new( @@ -309,17 +309,22 @@ impl traits::Service for OT { Ok(Some(ok)) } _ => { - warn!(cmd = as_debug!(message); "Unknown ot command"); + warn!(cmd = ?message, "Unknown ot command"); Ok(None) } } } async fn fsevent(&mut self, info: &super::types::ChannelInfo, event: FSEvent) -> Result<()> { - trace!(event = as_debug!(event), file_path = self.path; "fs event"); + trace!(?event, file_path = self.path, "fs event"); match event { FSEvent::Modify(path) => { - trace!(condition = (path == self.path), path = path, file_path = self.path; "Conditional time"); + trace!( + condition = (path == self.path), + path = path, + file_path = self.path, + "Conditional time" + ); if path == self.path { let new_contents = fs::read(&path).await?; @@ -369,11 +374,11 @@ impl traits::Service for OT { Ok(()) } FSEvent::Err(err) => { - error!(error = err; "Error in FS event listener"); + error!(err, "Error in FS event listener"); Ok(()) } _ => { - debug!(message = as_debug!(event); "Ignoing FS event"); + debug!(message = ?event, "Ignoing FS event"); Ok(()) } } diff --git a/services/src/output.rs b/services/src/output.rs index 157dcab..a56c92f 100644 --- a/services/src/output.rs +++ b/services/src/output.rs @@ -10,9 +10,9 @@ use std::{ }; use async_trait::async_trait; -use log::{as_debug, debug, warn}; use prost_types::Timestamp; use tokio::sync::RwLock; +use tracing::{debug, warn}; use super::traits; use super::types::pty::Pty; @@ -138,7 +138,7 @@ impl traits::Service for Output { } goval::command::Body::ResizeTerm(_) => {} _ => { - debug!(msg = as_debug!(message); "New message"); + debug!(?message, "New message"); } } Ok(None) diff --git a/services/src/presence.rs b/services/src/presence.rs index a912fc6..6a703cc 100644 --- a/services/src/presence.rs +++ b/services/src/presence.rs @@ -3,11 +3,11 @@ pub struct Presence { files: HashMap, } use crate::{ClientInfo, IPCMessage, SendSessions}; -use log::{as_debug, info, warn}; use std::{ collections::HashMap, time::{SystemTime, UNIX_EPOCH}, }; +use tracing::{info, warn}; use super::traits; use anyhow::{format_err, Result}; @@ -92,7 +92,7 @@ impl traits::Service for Presence { Ok(None) } _ => { - warn!(cmd = as_debug!(message); "Unknown presence command"); + warn!(cmd = ?message, "Unknown presence command"); Ok(None) } } @@ -160,7 +160,7 @@ impl traits::Service for Presence { )); } - info!(e = as_debug!(part); "Presence#detach"); + info!(?part, "Presence#detach"); info.send(part, SendSessions::EveryoneExcept(session)) .await?; Ok(()) diff --git a/services/src/shell.rs b/services/src/shell.rs index d924dd0..d74f041 100644 --- a/services/src/shell.rs +++ b/services/src/shell.rs @@ -4,8 +4,8 @@ pub struct Shell { use std::{collections::HashMap, sync::Arc}; use async_trait::async_trait; -use log::{as_debug, debug}; use tokio::sync::RwLock; +use tracing::debug; use super::traits; use super::types::pty::Pty; @@ -49,7 +49,7 @@ impl traits::Service for Shell { self.pty.resize(size.rows as u16, size.cols as u16)? } _ => { - debug!(msg = as_debug!(message); "New message"); + debug!(?message, "New message"); } } Ok(None) diff --git a/services/src/toolchain.rs b/services/src/toolchain.rs index 153e992..9610df5 100644 --- a/services/src/toolchain.rs +++ b/services/src/toolchain.rs @@ -1,7 +1,7 @@ pub struct Toolchain {} use super::traits; use async_trait::async_trait; -use log::{as_debug, debug}; +use tracing::debug; use anyhow::{format_err, Result}; @@ -52,7 +52,7 @@ impl traits::Service for Toolchain { Ok(Some(toolchain)) } _ => { - debug!(msg = as_debug!(message); "Unrecognized command :/"); + debug!(?message, "Unrecognized command :/"); Ok(None) } } diff --git a/services/src/types/channel_info.rs b/services/src/types/channel_info.rs index d699e64..70499df 100644 --- a/services/src/types/channel_info.rs +++ b/services/src/types/channel_info.rs @@ -3,8 +3,8 @@ use std::sync::Arc; use anyhow::Result; use goval; -use log::error; use tokio::sync::RwLock; +use tracing::error; use crate::config::dotreplit::DotReplit; diff --git a/services/src/types/fs_watcher.rs b/services/src/types/fs_watcher.rs index e94edfa..5cb62d8 100644 --- a/services/src/types/fs_watcher.rs +++ b/services/src/types/fs_watcher.rs @@ -1,10 +1,10 @@ -use log::{as_debug, error}; use notify_debouncer_full::{ new_debouncer, notify::{self, event::ModifyKind, Event, EventKind, RecommendedWatcher, Watcher}, DebounceEventResult, Debouncer, }; use serde::Serialize; +use tracing::error; use anyhow::Result; @@ -61,7 +61,7 @@ impl FSWatcher { } }), Err(errors) => errors.iter().for_each(|error| { - error!(error = as_debug!(error); "Error in debouncer"); + error!(?error, "Error in debouncer"); debounce_writer .send(ChannelMessage::FSEvent(FSEvent::Err(error.to_string()))) .expect("TODO: handle this"); diff --git a/services/src/types/proc.rs b/services/src/types/proc.rs index e7c36aa..bedfea1 100644 --- a/services/src/types/proc.rs +++ b/services/src/types/proc.rs @@ -8,12 +8,12 @@ use std::{ use crate::{ChannelMessage, IPCMessage, SendSessions}; use anyhow::Result; -use log::{error, trace}; use tokio::{ io::{AsyncReadExt, AsyncWrite, AsyncWriteExt, ReadBuf}, process::ChildStdin, sync::RwLock, }; +use tracing::{error, trace}; struct CmdWriter { channel: i32, diff --git a/services/src/types/pty.rs b/services/src/types/pty.rs index 019a439..04bb666 100644 --- a/services/src/types/pty.rs +++ b/services/src/types/pty.rs @@ -1,5 +1,4 @@ // use futures_util::{future::abortable, stream::AbortHandle}; -use log::{as_display, as_error, error}; use portable_pty::{Child, PtyPair, PtySize}; use std::{ collections::{HashMap, VecDeque}, @@ -7,6 +6,7 @@ use std::{ sync::{atomic::AtomicBool, Arc}, time::Duration, }; +use tracing::error; use crate::ChannelMessage; @@ -196,17 +196,17 @@ impl Pty { match contact_clone.send(ChannelMessage::ProcessDead(exit_code)) { Ok(_) => {} Err(err) => { - error!(err = as_error!(err); "PTY child proc reaper errored when alerting channel") + error!(%err, "PTY child proc reaper errored when alerting channel") } } } Err(err) => { - error!(err = as_display!(err); "PTY child proc reaper errored") + error!(%err, "PTY child proc reaper errored") } } } Err(err) => { - error!(err = as_error!(err); "Join error on pty child proc reaper") + error!(%err, "Join error on pty child proc reaper") } } }); diff --git a/src/database.rs b/src/database.rs index 881a9c3..07e71fa 100644 --- a/src/database.rs +++ b/src/database.rs @@ -1,9 +1,9 @@ use anyhow::Result; -use log::{debug, warn}; use migration::MigratorTrait; use sea_orm::{ConnectOptions, Database}; use std::time::Duration; use tokio::sync::OnceCell; +use tracing::{debug, warn}; pub static DATABASE: OnceCell = OnceCell::const_new(); diff --git a/src/goval_server.rs b/src/goval_server.rs index ef205ac..90763b4 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -19,8 +19,8 @@ use std::{net::SocketAddr, sync::LazyLock}; use tokio::sync::{mpsc::UnboundedSender, Mutex}; use futures_util::{SinkExt, StreamExt}; -use log::{as_debug, as_display, as_error, debug, error, info, trace, warn}; use tokio::sync::mpsc; +use tracing::{debug, error, info, trace, warn}; use crate::{ CHANNEL_MESSAGES, CHANNEL_METADATA, CHANNEL_SESSIONS, LAST_SESSION_USING_CHANNEL, MAX_SESSION, @@ -100,7 +100,7 @@ async fn on_wsv2_upgrade(socket: WebSocket, token: String, state: AppState, addr { Ok(_) => {} Err(err) => { - error!(error = as_display!(err); "accept_connection errored") + error!(?err, "accept_connection errored") } }; } @@ -125,7 +125,7 @@ async fn handle_message( let cmd_body = match cmd.body { None => { - error!(command = as_debug!(cmd); "MISSING COMMAND BODY"); + error!(?cmd, "MISSING COMMAND BODY"); return; } Some(body) => body, @@ -145,7 +145,7 @@ async fn handle_message( match sender.send(message.replace_cmd(pong)) { Ok(_) => {} Err(err) => { - error!(error = as_error!(err);"Error occured while sending Pong"); + error!(?err, "Error occured while sending Pong"); } } } else { @@ -154,7 +154,7 @@ async fn handle_message( } goval::command::Body::OpenChan(open_chan) => { if let Err(err) = open_channel(open_chan, message, max_channel, session_map).await { - error!(error = as_display!(err); "Error in open chan handler") + error!(?err, "Error in open chan handler") } } @@ -164,7 +164,7 @@ async fn handle_message( match detach_channel(close_chan.id, message.session, true).await { Ok(_) => {} Err(err) => { - error!(error = as_display!(err), session = message.session, channel = close_chan.id; + error!(%err, session = message.session, channel = close_chan.id, "Error occured while detaching from channel") } } @@ -181,7 +181,7 @@ async fn handle_message( queue.push(input); to_continue = true; } else { - error!(pty_id = pty_id; "Couldn't find pty to write to"); + error!(pty_id, "Couldn't find pty to write to"); } if to_continue { @@ -262,7 +262,7 @@ async fn open_channel( name: _channel_name.clone(), }; - trace!(channel = channel_id; "Awaiting queue write"); + trace!(channel = channel_id, "Awaiting queue write"); let (writer, reader) = mpsc::unbounded_channel(); @@ -274,7 +274,7 @@ async fn open_channel( let mut metadata = CHANNEL_METADATA.write().await; metadata.insert(channel_id_held, service_data.clone()); drop(metadata); - trace!(channel = channel_id_held; "Added channel to queue list"); + trace!(channel = channel_id_held, "Added channel to queue list"); tokio::spawn(async move { let channel = homeval_services::Channel::new( @@ -373,7 +373,7 @@ async fn open_channel( .and_modify(|channels| channels.push(channel_id_held)); } else { warn!( - service = open_chan.service; + service = open_chan.service, "Missing service requested by openChan" ) } @@ -381,7 +381,7 @@ async fn open_channel( } async fn detach_channel(channel: i32, session: i32, forced: bool) -> Result<()> { - trace!(session = session, channel = channel, forced = forced; "Client is closing a channel"); + trace!(session, channel, forced, "Client is closing a channel"); SESSION_CHANNELS .write() @@ -405,7 +405,7 @@ async fn detach_channel(channel: i32, session: i32, forced: bool) -> Result<()> Some(arr) => { arr.retain(|sess| *sess != session); if arr.is_empty() { - trace!(channel = channel; "Shutting down channel"); + trace!(channel, "Shutting down channel"); queue.send(ChannelMessage::Shutdown)?; tokio::spawn(async move { @@ -416,11 +416,11 @@ async fn detach_channel(channel: i32, session: i32, forced: bool) -> Result<()> LAST_SESSION_USING_CHANNEL.write().await.remove(&channel); }); } else { - trace!(sessions = as_debug!(arr); "Sessions still remain on channel"); + trace!(sessions = ?arr, "Sessions still remain on channel"); } } None => { - warn!(channel = channel; "Missing CHANNEL_SESSIONS"); + warn!(channel, "Missing CHANNEL_SESSIONS"); } } @@ -446,9 +446,9 @@ async fn accept_connection( client: ClientInfo, addr: SocketAddr, ) -> Result<()> { - info!(peer_address = as_display!(addr); "New connection"); + info!(peer_address = %addr, "New connection"); - info!(client = as_debug!(client); "New client"); + info!(?client, "New client"); SESSION_CLIENT_INFO .write() @@ -500,49 +500,53 @@ async fn accept_connection( tokio::spawn(async move { while let Some(_msg) = read.next().await { match _msg { - Ok(msg) => match msg { - WsMessage::Binary(buf) => { - let _message: anyhow::Result = buf.try_into(); - let message = match _message { - Ok(mut msg) => { - msg.session = session; - msg - } - Err(err) => { - error!(error = as_display!(err), session = session; "Error decoding message from client"); - continue; - } - }; + Ok(msg) => { + match msg { + WsMessage::Binary(buf) => { + let _message: anyhow::Result = buf.try_into(); + let message = match _message { + Ok(mut msg) => { + msg.session = session; + msg + } + Err(err) => { + error!(%err, session, "Error decoding message from client"); + continue; + } + }; - if let Err(err) = propagate.send(message) { - error!(session = session, error = as_error!(err); "An error occured when enqueing message to global message queue") + if let Err(err) = propagate.send(message) { + error!(session = session, ?err, "An error occured when enqueing message to global message queue") + } } - } - WsMessage::Close(_) => { - warn!(session = session; "CLOSING SESSION"); - for _channel in SESSION_CHANNELS.read().await.get(&session).unwrap().iter() - { - let channel = *_channel; - tokio::spawn(async move { - match detach_channel(channel, session, true).await { - Ok(_) => {} - Err(err) => { - error!(error = as_display!(err), session = session, channel = channel; "Error occured while detaching from channel") + WsMessage::Close(_) => { + warn!(session, "CLOSING SESSION"); + for _channel in + SESSION_CHANNELS.read().await.get(&session).unwrap().iter() + { + let channel = *_channel; + tokio::spawn(async move { + match detach_channel(channel, session, true).await { + Ok(_) => {} + Err(err) => { + error!(%err, session, channel, "Error occured while detaching from channel") + } } - } - }); - } + }); + } - SESSION_MAP.write().await.remove(&session); - SESSION_CLIENT_INFO.write().await.remove(&session); - SESSION_CHANNELS.write().await.remove(&session); - warn!(session = session; "CLOSED SESSION"); + SESSION_MAP.write().await.remove(&session); + SESSION_CLIENT_INFO.write().await.remove(&session); + SESSION_CHANNELS.write().await.remove(&session); + warn!(session, "CLOSED SESSION"); + } + _ => {} } - _ => {} - }, + } Err(err) => { error!( - session = session, error = as_error!(err); + session = session, + ?err, "An error occured while reading messages" ); } @@ -555,7 +559,8 @@ async fn accept_connection( Ok(_) => {} Err(err) => { error!( - session = i.session, error = as_error!(err); + session = i.session, + ?err, "An error occured while sending a message" ) } diff --git a/src/main.rs b/src/main.rs index be04797..3bae15e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,8 +4,8 @@ use std::sync::LazyLock; use std::time::Instant; use std::{collections::HashMap, io::Error, sync::Arc}; -use log::{debug, info}; use tokio::sync::{mpsc, Mutex, RwLock}; +use tracing::{debug, info}; use homeval_services::{ config::dotreplit::DotReplit, @@ -80,6 +80,7 @@ mod goval_server; #[tokio::main] async fn main() -> Result<(), Error> { + tracing_subscriber::fmt::init(); debug!("Initializing lazy statics"); LazyLock::force(&START_TIME); LazyLock::force(&CPU_STATS); @@ -89,7 +90,6 @@ async fn main() -> Result<(), Error> { std::env::set_var("HOMEVAL_START_DIR", std::env::current_dir()?); // console_subscriber::init(); - env_logger::try_init().unwrap(); #[cfg(feature = "database")] database::setup().await.unwrap(); diff --git a/src/parse_paseto.rs b/src/parse_paseto.rs index 3ce4514..a9042c1 100644 --- a/src/parse_paseto.rs +++ b/src/parse_paseto.rs @@ -10,7 +10,7 @@ static KEYS: tokio::sync::OnceCell> = tokio::sync::OnceCell::const_new(); #[cfg(feature = "verify_connections")] -use log::{as_display, warn}; +use tracing::warn; fn parse_noverify(input: &str) -> Result<(Vec, bool)> { let token: UntrustedToken = match UntrustedToken::try_from(input) { @@ -141,7 +141,7 @@ pub async fn parse(token: &str) -> Result { } Err(err) => { warn!( - error = as_display!(err); + %err, "Error in paseto parser + verification, falling back to non verifying parser" ); (msg, is_secure) = parse_noverify(token)?; diff --git a/src/repldb_server.rs b/src/repldb_server.rs index 80dca2b..5ecff11 100644 --- a/src/repldb_server.rs +++ b/src/repldb_server.rs @@ -6,11 +6,11 @@ use axum::{ Form, Router, }; use entity::repldb; -use log::{as_error, error, info, warn}; use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; use sea_query::OnConflict; use serde::Deserialize; use std::{collections::HashMap, net::SocketAddr}; +use tracing::{error, info, warn}; pub async fn start_server() -> Result<()> { if crate::DATABASE.get().is_none() { @@ -66,7 +66,7 @@ async fn set_value(Form(data): Form>) -> StatusCode { match result { Ok(_) => {} Err(err) => { - error!(error = as_error!(err); "Encountered error inserting key into database"); + error!(?err, "Encountered error inserting key into database"); return StatusCode::INTERNAL_SERVER_ERROR; } } @@ -88,7 +88,7 @@ async fn get_value(Path(key): Path) -> (StatusCode, String) { Some(data) => (StatusCode::OK, data.value), }, Err(err) => { - error!(error = as_error!(err); "Encountered error reading key from database"); + error!(?err, "Encountered error reading key from database"); (StatusCode::INTERNAL_SERVER_ERROR, "".to_string()) } } @@ -110,7 +110,7 @@ async fn delete_value(Path(key): Path) -> StatusCode { } } Err(err) => { - error!(error = as_error!(err); "Encountered error deleting key from database"); + error!(?err, "Encountered error deleting key from database"); StatusCode::INTERNAL_SERVER_ERROR } } @@ -150,7 +150,7 @@ async fn list_keys(Query(__prefix): Query) -> (StatusCode, String) { (StatusCode::OK, keys) } Err(err) => { - error!(error = as_error!(err); "Encountered error listing keys in database"); + error!(?err, "Encountered error listing keys in database"); (StatusCode::INTERNAL_SERVER_ERROR, "".to_string()) } } diff --git a/src/replspace_server.rs b/src/replspace_server.rs index 9f8b534..1cb6188 100644 --- a/src/replspace_server.rs +++ b/src/replspace_server.rs @@ -7,10 +7,10 @@ use axum::{ routing::{get, post}, Json, Router, }; -use log::{as_debug, debug, error, info}; use serde::{Deserialize, Serialize}; use textnonce::TextNonce; use tokio::sync::mpsc::channel; +use tracing::{debug, error, info}; use crate::{ChannelMessage, ReplspaceMessage}; @@ -50,7 +50,7 @@ struct GithubTokenReq { async fn get_gh_token(_query: Option>) -> (StatusCode, Json) { let session; if let Some(query) = _query { - debug!(channel = query.channel; "Got git askpass"); + debug!(channel = query.channel, "Got git askpass"); let last_session = crate::LAST_SESSION_USING_CHANNEL.read().await; session = *last_session.get(&query.channel).unwrap_or(&0); @@ -93,7 +93,7 @@ async fn get_gh_token(_query: Option>) -> (StatusCode, Jso ReplspaceMessage::GithubTokenRes(token) => token, _ => { error!( - result = as_debug!(res); + result = ?res, "Got unexpected result in replspace api github token fetcher" ); return ( @@ -134,7 +134,7 @@ async fn open_file(Json(query): Json) -> (StatusCode, Json) -> (StatusCode, Json { error!( - result = as_debug!(res); + result = ?res, "Got unexpected result in replspace api github token fetcher" ); ( From d0ff67ba6ca3fde3bb3cb8edc6df2495114cdb65 Mon Sep 17 00:00:00 2001 From: Ray Date: Sun, 4 Feb 2024 03:40:52 -0600 Subject: [PATCH 055/103] feat: add docker support --- Dockerfile | 51 +++++++++++++++++++++++++++++++++++++++++++++ protobuf/Cargo.toml | 4 ++++ 2 files changed, 55 insertions(+) create mode 100644 Dockerfile diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1f3acc8 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,51 @@ +FROM debian:buster-slim as base + +RUN apt update +RUN apt install -y \ + openssl + +# Setup the rust environment + +FROM base as setup + +RUN apt-get install -y \ + build-essential \ + curl \ + libssl-dev \ + pkg-config \ + protobuf-compiler +RUN apt-get update + +RUN curl https://sh.rustup.rs -sSf | sh -s -- --profile minimal --default-toolchain nightly -y +ENV PATH="/root/.cargo/bin:${PATH}" +RUN rustup update + +RUN USER=root cargo new --bin app +WORKDIR /app + +# Build the project + +FROM setup as build + +COPY ./Cargo.toml ./Cargo.toml +COPY ./Cargo.lock ./Cargo.lock +COPY ./migration ./migration +COPY ./entity ./entity +COPY ./services ./services +COPY ./protobuf ./protobuf + +RUN cargo build --locked --release +RUN rm src/*.rs + +COPY ./src ./src + +RUN rm ./target/release/deps/homeval* +RUN cargo install --path . + +# Runtime + +FROM base as runtime + +COPY --from=build /app/target/release/homeval . + +ENTRYPOINT [ "./homeval" ] diff --git a/protobuf/Cargo.toml b/protobuf/Cargo.toml index 5d0be5b..dfc462a 100644 --- a/protobuf/Cargo.toml +++ b/protobuf/Cargo.toml @@ -5,6 +5,10 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[lib] +name = "protobuf" +path = "src/lib.rs" + [dependencies] prost = "0.12.3" prost-types = "0.12.3" From c5273872afb8927fbd1c848eab522b708c2be1ac Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sun, 4 Feb 2024 12:57:58 -0800 Subject: [PATCH 056/103] feat(docker): Add container metadata --- Dockerfile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Dockerfile b/Dockerfile index 1f3acc8..35d8340 100644 --- a/Dockerfile +++ b/Dockerfile @@ -48,4 +48,10 @@ FROM base as runtime COPY --from=build /app/target/release/homeval . +# Container metadata + +LABEL org.opencontainers.image.source=https://github.com/goval-community/homeval +LABEL org.opencontainers.image.description="Custom replit eval server implementation" +LABEL org.opencontainers.image.licenses="AGPL-3.0-only" + ENTRYPOINT [ "./homeval" ] From 52d091d268a3a5efbf1660e4e62088420aea35fc Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sun, 4 Feb 2024 13:03:17 -0800 Subject: [PATCH 057/103] ci(docker): Build docker image in CI --- .github/workflows/ci.yml | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d1777c3..1bab1b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,7 @@ { "on": { "push": { "branches": "main" }, "pull_request": {} }, "name": "CI", - "permissions": { "security-events": "write" }, + "permissions": { "security-events": "write", "packages": "write" }, "jobs": { "enforce-clippy": @@ -140,5 +140,30 @@ }, ], }, + "docker-build": + { + "name": "Build & Push Docker Container", + "needs": ["build"], + "runs-on": "ubuntu-latest", + "steps": + [ + { + "name": "Checkout", + "uses": "actions/checkout@v4", + }, + { + "name": "Build Image", + "run": "docker buildx build -t homeval:${{ github.sha }} .", + }, + { + "name": "Log In to Registry", + "run": 'echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin', + }, + { + "name": "Push Image", + "run": "docker push ghcr.io/goval-community/homeval:${{ github.sha }}", + }, + ], + }, }, } From b6458f368ec95e1913c25d97c805b75f2adaa0d9 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sun, 4 Feb 2024 13:40:55 -0800 Subject: [PATCH 058/103] ci(docker): Correctly tag container image --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1bab1b9..41dee90 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -153,7 +153,7 @@ }, { "name": "Build Image", - "run": "docker buildx build -t homeval:${{ github.sha }} .", + "run": "docker buildx build -t ghcr.io/goval-community/homeval:${{ github.sha }} .", }, { "name": "Log In to Registry", From 12b540d1ffa1d088d68930443e4e4fd495d841cc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 13:15:19 +0000 Subject: [PATCH 059/103] build(deps): bump tokio from 1.35.1 to 1.36.0 Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.35.1 to 1.36.0. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.35.1...tokio-1.36.0) --- updated-dependencies: - dependency-name: tokio dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- migration/Cargo.toml | 2 +- services/Cargo.toml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2efb887..ca5b511 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3426,9 +3426,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 1b349aa..fd1e13d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ prost = "0.12.3" prost-types = "0.12.3" serde_json = "1.0.113" serde = { version = "1.0.196", features = ["derive"] } -tokio = {version="1.26.0", features = ["full"]} +tokio = {version="1.36.0", features = ["full"]} base64 = "0.21.0" futures = "0.3.28" axum = { version = "0.7.4", features = ["ws"] } diff --git a/migration/Cargo.toml b/migration/Cargo.toml index 946718f..b950cd2 100644 --- a/migration/Cargo.toml +++ b/migration/Cargo.toml @@ -9,7 +9,7 @@ name = "migration" path = "src/lib.rs" [dependencies] -tokio = { version = "1.28.2", features = ["full"]} +tokio = { version = "1.36.0", features = ["full"]} # async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] diff --git a/services/Cargo.toml b/services/Cargo.toml index 437236a..a58034a 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -20,7 +20,7 @@ ropey = "1.6.0" serde = "1.0.196" serde_json = "1.0.113" similar = "2.2.1" -tokio = "1.28.2" +tokio = "1.36.0" tracing = "0.1.40" tracing-futures = "0.2.5" From 12b6e79d526aaf911d8cc070a804c74f15c20daf Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 17 Feb 2024 16:50:05 -0800 Subject: [PATCH 060/103] ci(docker): Move docker to it's own workflow --- .github/workflows/ci.yml | 8 ++++++-- .github/workflows/docker.yml | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 41dee90..6476ebc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,11 @@ { - "on": { "push": { "branches": "main" }, "pull_request": {} }, + "on": + { + "push": { "branches": ["pure-rust"] }, + "pull_request": {}, + }, "name": "CI", - "permissions": { "security-events": "write", "packages": "write" }, + "permissions": { "security-events": "write" }, "jobs": { "enforce-clippy": diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..cb8509e --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,32 @@ +{ + "on": { "push": { "branches": ["pure-rust"] } }, + "name": "Docker", + "permissions": { "packages": "write" }, + "jobs": + { + "docker-build": + { + "name": "Build & Push Docker Container", + "runs-on": "ubuntu-latest", + "steps": + [ + { + "name": "Checkout", + "uses": "actions/checkout@v4", + }, + { + "name": "Build Image", + "run": "docker buildx build -t ghcr.io/goval-community/homeval:${{ github.sha }} .", + }, + { + "name": "Log In to Registry", + "run": 'echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin', + }, + { + "name": "Push Image", + "run": "docker push ghcr.io/goval-community/homeval:${{ github.sha }}", + }, + ], + }, + }, +} From 5fe34e02968c666a41198fabacd9a65086fc5489 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 17 Feb 2024 16:50:36 -0800 Subject: [PATCH 061/103] ci(build,clippy): Setup merge queue ci runs --- .github/workflows/ci.yml | 26 +------------------------- 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6476ebc..e3dbf97 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,6 +3,7 @@ { "push": { "branches": ["pure-rust"] }, "pull_request": {}, + "merge_group": {}, }, "name": "CI", "permissions": { "security-events": "write" }, @@ -144,30 +145,5 @@ }, ], }, - "docker-build": - { - "name": "Build & Push Docker Container", - "needs": ["build"], - "runs-on": "ubuntu-latest", - "steps": - [ - { - "name": "Checkout", - "uses": "actions/checkout@v4", - }, - { - "name": "Build Image", - "run": "docker buildx build -t ghcr.io/goval-community/homeval:${{ github.sha }} .", - }, - { - "name": "Log In to Registry", - "run": 'echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u $ --password-stdin', - }, - { - "name": "Push Image", - "run": "docker push ghcr.io/goval-community/homeval:${{ github.sha }}", - }, - ], - }, }, } From 342974c1a0be608e1c0abe99ca13b838bb6cc6e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 18 Feb 2024 01:04:14 +0000 Subject: [PATCH 062/103] build(deps): bump hyper-util from 0.1.2 to 0.1.3 Bumps [hyper-util](https://github.com/hyperium/hyper-util) from 0.1.2 to 0.1.3. - [Release notes](https://github.com/hyperium/hyper-util/releases) - [Changelog](https://github.com/hyperium/hyper-util/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/hyper-util/compare/v0.1.2...v0.1.3) --- updated-dependencies: - dependency-name: hyper-util dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca5b511..626fc3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1219,9 +1219,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdea9aac0dbe5a9240d68cfd9501e2db94222c6dc06843e06640b9e07f0fdc67" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" dependencies = [ "bytes", "futures-channel", diff --git a/Cargo.toml b/Cargo.toml index fd1e13d..77dbb71 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ entity = { path = "entity", optional = true} sea-query = { version = "0.30.7", optional = true } pasetors = { version = "0.6.7", default-features = false, features = ["v2"] } hyper = { version = "1.1.0", features = ["http1", "http2", "client"], optional = true } -hyper-util = { version = "0.1.2", features = ["client", "client-legacy", "http1", "http2"], optional = true } +hyper-util = { version = "0.1.3", features = ["client", "client-legacy", "http1", "http2"], optional = true } hyper-tls = { version = "0.6.0", optional = true } http-body-util = { version = "0.1.0", optional = true } anyhow = "1.0.71" From 9d245f03e51fe90d1feb12716770de1345394f68 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 18 Feb 2024 01:04:14 +0000 Subject: [PATCH 063/103] build(deps): bump chrono from 0.4.33 to 0.4.34 Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.33 to 0.4.34. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.33...v0.4.34) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca5b511..7024b5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -420,9 +420,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "chrono" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" +checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" dependencies = [ "android-tzdata", "iana-time-zone", diff --git a/Cargo.toml b/Cargo.toml index fd1e13d..883bcbf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,7 @@ toml = "0.8.8" textnonce = "1.0.0" -chrono = { version = "0.4.33", default-features = false, features = ["std", "libc", "clock"], optional = true } +chrono = { version = "0.4.34", default-features = false, features = ["std", "libc", "clock"], optional = true } chrono-tz = { version = "0.8.2", optional = true } From 9ddbbfa7b58290f5793eed8441d3eb86e180414f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 18 Feb 2024 01:04:18 +0000 Subject: [PATCH 064/103] build(deps): bump toml from 0.8.8 to 0.8.10 Bumps [toml](https://github.com/toml-rs/toml) from 0.8.8 to 0.8.10. - [Commits](https://github.com/toml-rs/toml/compare/toml-v0.8.8...toml-v0.8.10) --- updated-dependencies: - dependency-name: toml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 30 +++++++++++++++++++++++++----- Cargo.toml | 2 +- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca5b511..2f47bde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2014,7 +2014,7 @@ version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b2685dd208a3771337d8d386a89840f0f43cd68be8dae90a5f8c2384effc9cd" dependencies = [ - "toml_edit", + "toml_edit 0.21.0", ] [[package]] @@ -3503,14 +3503,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_edit 0.22.6", ] [[package]] @@ -3527,12 +3527,23 @@ name = "toml_edit" version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow 0.5.34", +] + +[[package]] +name = "toml_edit" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.1", ] [[package]] @@ -4087,6 +4098,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d90f4e0f530c4c69f62b80d839e9ef3855edc9cba471a160c4d692deed62b401" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.10.1" diff --git a/Cargo.toml b/Cargo.toml index fd1e13d..dd0ecf6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ futures = "0.3.28" axum = { version = "0.7.4", features = ["ws"] } cpu-time = "1.0.0" deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } -toml = "0.8.8" +toml = "0.8.10" textnonce = "1.0.0" From 9541d5aa24ba2fd5ac1f821644af76c6b005c47e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 18 Feb 2024 01:04:38 +0000 Subject: [PATCH 065/103] build(deps): bump sea-orm-migration from 0.12.12 to 0.12.14 Bumps [sea-orm-migration](https://github.com/SeaQL/sea-orm) from 0.12.12 to 0.12.14. - [Release notes](https://github.com/SeaQL/sea-orm/releases) - [Changelog](https://github.com/SeaQL/sea-orm/blob/0.12.14/CHANGELOG.md) - [Commits](https://github.com/SeaQL/sea-orm/compare/0.12.12...0.12.14) --- updated-dependencies: - dependency-name: sea-orm-migration dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 16 ++++++++-------- migration/Cargo.toml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca5b511..79854e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2480,9 +2480,9 @@ dependencies = [ [[package]] name = "sea-orm" -version = "0.12.12" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cbf88748872fa54192476d6d49d0775e208566a72656e267e45f6980b926c8d" +checksum = "6632f499b80cc6aaa781b302e4c9fae663e0e3dcf2640e9d80034d5b10731efe" dependencies = [ "async-stream", "async-trait", @@ -2508,9 +2508,9 @@ dependencies = [ [[package]] name = "sea-orm-cli" -version = "0.12.12" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f17eb697616be2f3e4ea3b468a44cfb6848750dec522fdef4caa44bf5a02beb" +checksum = "465ea2308d4716837e9af4a2cff8e14c28135867a580bb93e9e03d408a3a6afb" dependencies = [ "chrono", "clap", @@ -2525,9 +2525,9 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "0.12.12" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0dbc880d47aa53c6a572e39c99402c7fad59b50766e51e0b0fc1306510b0555" +checksum = "ec13bfb4c4aef208f68dbea970dd40d13830c868aa8dcb4e106b956e6bb4f2fa" dependencies = [ "heck", "proc-macro2", @@ -2539,9 +2539,9 @@ dependencies = [ [[package]] name = "sea-orm-migration" -version = "0.12.12" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42807e13d38edd4cc1f9cbb370df898d43a9a143f6161dcdb8424a6de002def" +checksum = "ac734b6e5610c2764056cc8495fbc293cd1c8ebe084fdfb74c3b0cdaaff9bb92" dependencies = [ "async-trait", "clap", diff --git a/migration/Cargo.toml b/migration/Cargo.toml index b950cd2..1f61adc 100644 --- a/migration/Cargo.toml +++ b/migration/Cargo.toml @@ -13,7 +13,7 @@ tokio = { version = "1.36.0", features = ["full"]} # async-std = { version = "1", features = ["attributes", "tokio1"] } [dependencies.sea-orm-migration] -version = "0.12.12" +version = "0.12.14" features = [ # Enable at least one `ASYNC_RUNTIME` and `DATABASE_DRIVER` feature if you want to run migration via CLI. # View the list of supported features at https://www.sea-ql.org/SeaORM/docs/install-and-config/database-and-async-runtime. From ebfef875511ba100e68144dc0840bd5f3cb6f5a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 18 Feb 2024 01:04:44 +0000 Subject: [PATCH 066/103] build(deps): bump sea-orm from 0.12.12 to 0.12.14 Bumps [sea-orm](https://github.com/SeaQL/sea-orm) from 0.12.12 to 0.12.14. - [Release notes](https://github.com/SeaQL/sea-orm/releases) - [Changelog](https://github.com/SeaQL/sea-orm/blob/0.12.14/CHANGELOG.md) - [Commits](https://github.com/SeaQL/sea-orm/compare/0.12.12...0.12.14) --- updated-dependencies: - dependency-name: sea-orm dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- entity/Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca5b511..5245201 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2480,9 +2480,9 @@ dependencies = [ [[package]] name = "sea-orm" -version = "0.12.12" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cbf88748872fa54192476d6d49d0775e208566a72656e267e45f6980b926c8d" +checksum = "6632f499b80cc6aaa781b302e4c9fae663e0e3dcf2640e9d80034d5b10731efe" dependencies = [ "async-stream", "async-trait", @@ -2525,9 +2525,9 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "0.12.12" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0dbc880d47aa53c6a572e39c99402c7fad59b50766e51e0b0fc1306510b0555" +checksum = "ec13bfb4c4aef208f68dbea970dd40d13830c868aa8dcb4e106b956e6bb4f2fa" dependencies = [ "heck", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index fd1e13d..b9cfbd7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ chrono = { version = "0.4.33", default-features = false, features = ["std", "lib chrono-tz = { version = "0.8.2", optional = true } -sea-orm = { version = "0.12.2", features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros", "postgres-array" ], optional = true } +sea-orm = { version = "0.12.14", features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros", "postgres-array" ], optional = true } migration = { path = "migration", optional = true} entity = { path = "entity", optional = true} sea-query = { version = "0.30.7", optional = true } diff --git a/entity/Cargo.toml b/entity/Cargo.toml index 400bea9..07922a5 100644 --- a/entity/Cargo.toml +++ b/entity/Cargo.toml @@ -9,5 +9,5 @@ path = "src/mod.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -sea-orm = "0.12.2" +sea-orm = "0.12.14" serde = "1.0.196" From 92c9812384d8aa5975b5cb3e73e3e229bb478ed2 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 17 Feb 2024 17:21:41 -0800 Subject: [PATCH 067/103] ci: Fix config This avoids double-running checks on merged commits since right now pure-rust has an open pr into main --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e3dbf97..3735309 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,7 @@ { "on": { - "push": { "branches": ["pure-rust"] }, + "push": { "branches": ["main"] }, "pull_request": {}, "merge_group": {}, }, From d5bfbcc36be61afdca7559beb3cd202f83ff0573 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 21:32:49 +0000 Subject: [PATCH 068/103] build(deps): bump mio from 0.8.10 to 0.8.11 Bumps [mio](https://github.com/tokio-rs/mio) from 0.8.10 to 0.8.11. - [Release notes](https://github.com/tokio-rs/mio/releases) - [Changelog](https://github.com/tokio-rs/mio/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/mio/compare/v0.8.10...v0.8.11) --- updated-dependencies: - dependency-name: mio dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9d9c912..878b5ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1502,9 +1502,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", From d6c25d5188428fb268d235d47ecc65ee459665cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 5 Mar 2024 02:26:51 +0000 Subject: [PATCH 069/103] build(deps): bump crc32fast from 1.3.2 to 1.4.0 Bumps [crc32fast](https://github.com/srijs/rust-crc32fast) from 1.3.2 to 1.4.0. - [Commits](https://github.com/srijs/rust-crc32fast/compare/v1.3.2...v1.4.0) --- updated-dependencies: - dependency-name: crc32fast dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- services/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 878b5ed..bb91a88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -557,9 +557,9 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" -version = "1.3.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" dependencies = [ "cfg-if", ] diff --git a/services/Cargo.toml b/services/Cargo.toml index a58034a..b37d146 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] anyhow = "1.0.71" async-trait = "0.1.68" -crc32fast = { version = "1.3.2", features = ["nightly"] } +crc32fast = { version = "1.4.0", features = ["nightly"] } deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } futures-util = "0.3.28" goval = { package = "protobuf", path = "../protobuf"} From 97413856739807911d289b19d39f08a5f1ce7fae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Mar 2024 13:06:15 +0000 Subject: [PATCH 070/103] build(deps): bump anyhow from 1.0.79 to 1.0.81 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.79 to 1.0.81. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.79...1.0.81) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- services/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 878b5ed..caeb4b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,9 +127,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "arrayvec" diff --git a/Cargo.toml b/Cargo.toml index 0e3d89e..d9d94bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,4 +60,4 @@ hyper = { version = "1.1.0", features = ["http1", "http2", "client"], optional = hyper-util = { version = "0.1.3", features = ["client", "client-legacy", "http1", "http2"], optional = true } hyper-tls = { version = "0.6.0", optional = true } http-body-util = { version = "0.1.0", optional = true } -anyhow = "1.0.71" +anyhow = "1.0.81" diff --git a/services/Cargo.toml b/services/Cargo.toml index a58034a..0e29a40 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0.71" +anyhow = "1.0.81" async-trait = "0.1.68" crc32fast = { version = "1.3.2", features = ["nightly"] } deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } From 06a534c8e695833f4f94af86a787990a5088720f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Apr 2024 13:58:25 +0000 Subject: [PATCH 071/103] build(deps): bump serde_json from 1.0.113 to 1.0.115 Bumps [serde_json](https://github.com/serde-rs/json) from 1.0.113 to 1.0.115. - [Release notes](https://github.com/serde-rs/json/releases) - [Commits](https://github.com/serde-rs/json/compare/v1.0.113...v1.0.115) --- updated-dependencies: - dependency-name: serde_json dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- services/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 878b5ed..1d02201 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2684,9 +2684,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.115" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" dependencies = [ "itoa", "ryu", diff --git a/Cargo.toml b/Cargo.toml index 0e3d89e..1223989 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ futures-util = "0.3.26" log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } prost = "0.12.3" prost-types = "0.12.3" -serde_json = "1.0.113" +serde_json = "1.0.115" serde = { version = "1.0.196", features = ["derive"] } tokio = {version="1.36.0", features = ["full"]} base64 = "0.21.0" diff --git a/services/Cargo.toml b/services/Cargo.toml index a58034a..0afca45 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -18,7 +18,7 @@ prost = "0.12.3" prost-types = "0.12.3" ropey = "1.6.0" serde = "1.0.196" -serde_json = "1.0.113" +serde_json = "1.0.115" similar = "2.2.1" tokio = "1.36.0" tracing = "0.1.40" From 055b50eb424c651686d133912f79dc5dcf83d19f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 15:09:03 +0000 Subject: [PATCH 072/103] build(deps): bump h2 from 0.4.2 to 0.4.4 Bumps [h2](https://github.com/hyperium/h2) from 0.4.2 to 0.4.4. - [Release notes](https://github.com/hyperium/h2/releases) - [Changelog](https://github.com/hyperium/h2/blob/master/CHANGELOG.md) - [Commits](https://github.com/hyperium/h2/compare/v0.4.2...v0.4.4) --- updated-dependencies: - dependency-name: h2 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 878b5ed..e3c666c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1004,9 +1004,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.4.2" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943" +checksum = "816ec7294445779408f36fe57bc5b7fc1cf59664059096c65f905c1c61f58069" dependencies = [ "bytes", "fnv", From 16b4ab9141d36c1972dc3e34e1c736174f6f04ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 15:48:29 +0000 Subject: [PATCH 073/103] build(deps): bump whoami from 1.4.1 to 1.5.1 Bumps [whoami](https://github.com/ardaku/whoami) from 1.4.1 to 1.5.1. - [Changelog](https://github.com/ardaku/whoami/blob/v1/CHANGELOG.md) - [Commits](https://github.com/ardaku/whoami/compare/v1.4.1...v1.5.1) --- updated-dependencies: - dependency-name: whoami dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 878b5ed..8b6ec7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3839,6 +3839,12 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.90" @@ -3913,9 +3919,13 @@ dependencies = [ [[package]] name = "whoami" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +dependencies = [ + "redox_syscall", + "wasite", +] [[package]] name = "winapi" From 6243c8a8b09f14deff9ec4bde89cfca1c8d0f066 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 13:57:08 +0000 Subject: [PATCH 074/103] build(deps): bump chrono-tz from 0.8.5 to 0.9.0 Bumps [chrono-tz](https://github.com/chronotope/chrono-tz) from 0.8.5 to 0.9.0. - [Release notes](https://github.com/chronotope/chrono-tz/releases) - [Changelog](https://github.com/chronotope/chrono-tz/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono-tz/compare/v0.8.5...v0.9.0) --- updated-dependencies: - dependency-name: chrono-tz dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 878b5ed..14c4bb9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,9 +433,9 @@ dependencies = [ [[package]] name = "chrono-tz" -version = "0.8.5" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d7b79e99bfaa0d47da0687c43aa3b7381938a62ad3a6498599039321f660b7" +checksum = "93698b29de5e97ad0ae26447b344c482a7284c737d9ddc5f9e52b74a336671bb" dependencies = [ "chrono", "chrono-tz-build", @@ -444,9 +444,9 @@ dependencies = [ [[package]] name = "chrono-tz-build" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" +checksum = "0c088aee841df9c3041febbb73934cfc39708749bf96dc827e3359cd39ef11b1" dependencies = [ "parse-zoneinfo", "phf", diff --git a/Cargo.toml b/Cargo.toml index 0e3d89e..b4f870e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,7 +48,7 @@ textnonce = "1.0.0" chrono = { version = "0.4.34", default-features = false, features = ["std", "libc", "clock"], optional = true } -chrono-tz = { version = "0.8.2", optional = true } +chrono-tz = { version = "0.9.0", optional = true } sea-orm = { version = "0.12.14", features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros", "postgres-array" ], optional = true } From 00d56c0b8dfc25a7c3c0fb908e8d8bb8f0f5c857 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Thu, 11 Apr 2024 14:08:17 -0700 Subject: [PATCH 075/103] feat(services): Implement fsevents --- .idea/.gitignore | 8 + .idea/homeval.iml | 15 ++ .idea/modules.xml | 8 + .idea/vcs.xml | 6 + README.md | 45 ++-- protobuf/src/goval.proto | 473 ++++++++++++++++++++++++++++++++++----- services/src/fsevents.rs | 130 +++++++++++ services/src/lib.rs | 10 +- services/src/output.rs | 2 + services/src/stub.rs | 1 + src/parse_paseto.rs | 2 +- 11 files changed, 619 insertions(+), 81 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/homeval.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 services/src/fsevents.rs diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/homeval.iml b/.idea/homeval.iml new file mode 100644 index 0000000..d24fb44 --- /dev/null +++ b/.idea/homeval.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..723db29 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 1b6a0a5..d014f4a 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,13 @@
License: AGPL-3.0-only - Services implemented: 15 + Services implemented: 12

Homeval is a custom server implementation of goval, replits evaluation protocol.

-# ⚠️ Stability -**⚠️ Homeval is still in early alpha and can be unstable so do not trust it with data you have not backed up. ⚠️** +> [!CAUTION] +> **⚠️ Homeval is still in early alpha and can be unstable so do not trust it with data you have not backed up. ⚠️** # License Homeval is licensed under GNU AGPL-3.0-only @@ -18,41 +18,46 @@ Homeval is licensed under GNU AGPL-3.0-only Unfortunately due to replit's TOS, AGPL programs cannot be run in public repls. Though, private repls are fine, as long as you still fulfill the terms of the license. This is due to all public repls being licensed under MIT, and GPL code cannot be included in a MIT licensed project. -# Running homeval +# Building homeval -## Installation 1. Git clone the repository 2. Install required dependencies - * If on macOS or linux: [Bun](https://bun.sh/) and [Git](https://git-scm.com/downloads) - * If on windows: [Node.js](https://nodejs.org/en/download), [Yarn v1](https://classic.yarnpkg.com/lang/en/docs/install/#windows-stable) and [Git for Windows](https://gitforwindows.org/) - * The [Protobuf Compiler](https://github.com/protocolbuffers/protobuf/releases) - * If using a debian linux based distro just run: `sudo apt install protobuf-compiler` - * [Rustup](https://rustup.rs/) - * And finally, [Ripgrep](https://github.com/BurntSushi/ripgrep#installation). + * [Git](https://git-scm.com/downloads) ( [Git for Windows](https://gitforwindows.org/) on windows) + * The [Protobuf Compiler](https://github.com/protocolbuffers/protobuf/releases) + * If using a debian linux based distro just run: `sudo apt install protobuf-compiler` + * [Rustup](https://rustup.rs/) + +# Running homeval + +## Required tools + +- [Git](https://git-scm.com/downloads) ( [Git for Windows](https://gitforwindows.org/) on windows) +- [Ripgrep](https://github.com/BurntSushi/ripgrep#installation). + ## Setup ### Database -Setup a [PostgreSQL](https://www.postgresql.org/) database and set the env var `$HOMEVAL_DB` to it's connection url. +Set up a [PostgreSQL](https://www.postgresql.org/) database and set the env var `$HOMEVAL_DB` to its connection url. If the database isn't setup repldb won't work, and file history won't persist through server restarts. ### Proper Authentication -> ⚠️ If you use someone elses key server it could let them authenticate as any user on your homeval instance +> [!WARNING] +> ⚠If you use someone else's key server it could let them authenticate as any user on your homeval instance Run [repl-key-server](https://github.com/Goval-Community/repl-key-server) on a repl and set the env var `$HOMEVAL_PASETO_KEY_URL` to `/keys`. ### Replspace api -> ⚠️ Likely won't work on windows +> [!IMPORTANT] +> This will not work on windows. To make use of this feature make sure that all files in `extras/` are placed in a directory contained in your `$PATH` on the machine running homeval. ## ⚠️ Notice for windows users On windows `cargo run` as well as invoking the built binary must happen inside the [Git Bash](https://gitforwindows.org/) shell. -Console and shell will not work, this will be fixed later. You should submit a bug report for other broken features. - ## Building Homeval can be built into a binary with `cargo build --release` the binary will then end up in `target/release/homeval` (make sure to set `RUST_LOG=INFO` when running this binary or you won't get any logs). @@ -83,7 +88,7 @@ Make a new file in `services/` name it with the format `.js` then | --- | --- | --- | --- | --- | | Linux[^linux] | ✅ | ✅ | ✅ | ✅[^linux-tests] | | macOS[^macos] | ✅ | ✅ | ✅ | ❎ | -| Windows | ✅ | ✅ | ❎[^windows] | ❎ | +| Windows | ✅ | ✅ | ✅ | ❎ | [^testing]: This marks if every release is officially tested for this target. @@ -94,10 +99,8 @@ Make a new file in `services/` name it with the format `.js` then [^linux-tests]: Currently, the only tested distribution is arch linux. Though all distros with an up to date GLIC *should* work. -[^windows]: Shell and Console support are currently unavailable on windows. - # TODO: -- [ ] Have windows builds feature complete - [ ] Debugger support -- [ ] Audio channel support \ No newline at end of file +- [ ] Pid2 Support +- [ ] Unit Tests \ No newline at end of file diff --git a/protobuf/src/goval.proto b/protobuf/src/goval.proto index 4bf37ce..98c7192 100644 --- a/protobuf/src/goval.proto +++ b/protobuf/src/goval.proto @@ -1,4 +1,4 @@ -// @replit/protocol 0.3.31 +// @replit/protocol 0.3.55 syntax = "proto3"; package goval; @@ -13,6 +13,7 @@ message Command { int32 session = 2; string ref = 1000; map traceInfo = 1001; + bool forceTrace = 1002; oneof body { OpenChannel openChan = 3; OpenChannelRes openChanRes = 4; @@ -24,7 +25,6 @@ message Command { Toast toast = 11; ProtocolError protocolError = 45; Redirect redirect = 12; - AlwaysOn alwaysOn = 13; RunMain runMain = 16; Clear clear = 17; string eval = 20; @@ -39,6 +39,7 @@ message Command { OutputBlockEndEvent outputBlockEndEvent = 444; sint32 exitCodeEvent = 445; bool splitStderrRequest = 446; + ShellMetadata shellMetadata = 447; SaneTerm saneTerm = 26; ResizeTerm resizeTerm = 27; State state = 28; @@ -51,6 +52,7 @@ message Command { File tryRemove = 36; File mkdir = 39; File stat = 368; + File resetNixFilesystem = 449; StatResult statRes = 369; TransferStart transferStart = 320; TransferChunk transferChunk = 321; @@ -119,6 +121,7 @@ message Command { PackageInfo packageInfo = 282; PackageInfoResp packageInfoResp = 283; PackageAdd packageAdd = 284; + PackageAddResponse packageAddResponse = 448; PackageRemove packageRemove = 285; PackageInstall packageInstall = 286; PackageInstallResponse packageInstallResponse = 290; @@ -181,6 +184,8 @@ message Command { NixChannelLatestStableResponse nixChannelLatestStableResponse = 419; NixPackageSearchRequest nixPackageSearchRequest = 420; NixPackageSearchResponse nixPackageSearchResponse = 421; + NixPackageInfoRequest nixPackageInfoRequest = 450; + NixPackageInfoResponse nixPackageInfoResponse = 451; UserEvent userEvent = 423; ReplspaceApiOpenFile replspaceApiOpenFile = 424; ReplspaceApiCloseFile replspaceApiCloseFile = 425; @@ -199,6 +204,13 @@ message Command { ReplspaceApiOpenMultipleFiles replspaceApiOpenMultipleFiles = 438; NixModulesGetRegistryRequest nixModulesGetRegistryRequest = 439; NixModulesGetRegistryResponse nixModulesGetRegistryResponse = 440; + ReplspaceApiShellTracker replspaceApiShellTracker = 442; + NixModuleConfigGetRequest nixModuleConfigGetRequest = 460; + NixModuleConfigGetResponse nixModuleConfigGetResponse = 461; + NixModuleConfigSetRequest nixModuleConfigSetRequest = 462; + NixModuleConfigSetResponse nixModuleConfigSetResponse = 463; + ReplspaceApiSSHTokenGetRequest replspaceApiSSHTokenGetRequest = 464; + ReplspaceApiSSHTokenGetResponse replspaceApiSSHTokenGetResponse = 465; } } @@ -231,10 +243,19 @@ message NixChannelLatestStableRequest {} message NixChannelLatestStableResponse { string channel = 1; } -message NixPackageSearchRequest { string query = 1; } +message NixPackageSearchRequest { + string query = 1; + oneof _filterBuilt { bool filterBuilt = 2; } +} message NixPackageSearchResponse { repeated NixPackage packages = 1; } +message NixPackageInfoRequest { string name = 1; } + +message NixPackageInfoResponse { + oneof _package { NixPackage package = 1; } +} + message StartLSP { string language = 1; string languageServerId = 2; @@ -339,8 +360,9 @@ message FileEvent { message Flush { enum Consistency { - PermanentStorage = 0; + DiskAndHistory = 0; Disk = 1; + History = 2; } Flush.Consistency consistency = 1; @@ -556,8 +578,6 @@ message ProtocolError { string text = 1; } message Redirect { string url = 1; } -message AlwaysOn { bool enable = 1; } - message RunMain { enum RunMode { RUN = 0; @@ -569,6 +589,8 @@ message RunMain { string filePath = 3; string runnerId = 4; bool fromHosting = 5; + string runID = 6; + int32 clientSession = 7; } message OpenChannel { @@ -634,7 +656,9 @@ message PortOpen { uint32 externalPort = 4; string comm = 5; repeated string cmdline = 6; + string cgroup = 8; uint32 pid = 7; + repeated uint32 pidChain = 9; } message PortClose { @@ -755,7 +779,15 @@ message ReplspaceApiGitHubToken { string token = 2; } -message ReplspaceApiOpenMultipleFiles { repeated string files = 1; } +message ReplspaceApiOpenMultipleFiles { + repeated string files = 1; + repeated string urls = 2; +} + +message ReplspaceApiShellTracker { + string cmd = 1; + string pwd = 2; +} message Focused {} @@ -783,6 +815,7 @@ message Exec { Exec.Lifecycle lifecycle = 6; bool splitStderr = 4; bool splitLogs = 5; + bool waitForEnv = 7; } message Package { @@ -811,7 +844,12 @@ message PackageInfo { Package pkg = 1; } message PackageInfoResp { Package pkg = 1; } -message PackageAdd { repeated Package pkgs = 1; } +message PackageAdd { + repeated Package pkgs = 1; + bool useNewResponse = 2; +} + +message PackageAddResponse { bool installedSystemDependencies = 1; } message PackageRemove { repeated Package pkgs = 1; } @@ -827,6 +865,7 @@ message PackageInstallResponse { int64 upmAddDurationMs = 3; int64 upmLockDurationMs = 4; int64 totalDurationMs = 5; + bool installedSystemDependencies = 6; } message PackageListSpecfile {} @@ -998,6 +1037,9 @@ message DotReplit { repeated string modules = 23; ExtensionConfig extension = 24; RulesConfig rules = 25; + SuggestionsConfig suggestions = 26; + ObjectStorageConfig objectStorage = 27; + AutoSaveConfig autoSave = 28; } message DotReplitEnvVar { @@ -1008,6 +1050,7 @@ message DotReplitEnvVar { message DotReplitPort { uint32 localPort = 1; uint32 externalPort = 2; + bool exposeLocalhost = 3; } message DotReplitHint { @@ -1022,6 +1065,21 @@ message DeploymentConfig { GCE = 0; CLOUDRUN = 1; STATIC = 2; + VM = 3; + AUTOSCALE = 4; + SCHEDULED = 5; + EXTENSION = 6; + } + + message RewriteRule { + string from = 1; + string to = 2; + } + + message Header { + string path = 1; + string name = 2; + string value = 3; } Exec run = 1; @@ -1029,6 +1087,8 @@ message DeploymentConfig { bool ignorePorts = 3; DeploymentConfig.Target target = 4; string publicDir = 5; + repeated DeploymentConfig.RewriteRule rewrites = 6; + repeated DeploymentConfig.Header responseHeaders = 7; } message ExtensionConfig { @@ -1039,6 +1099,8 @@ message ExtensionConfig { string staticDirectory = 5; } +message SuggestionsConfig { repeated string extensions = 1; } + message NixConfig { string channel = 1; } message HostingConfig { @@ -1161,7 +1223,12 @@ message NixModule { repeated FormatterOption formatters = 13; } -message NixModulesChanged { repeated NixModule modules = 1; } +message NixModulesChanged { + repeated NixModule modules = 1; + repeated NixModuleConfigValue moduleConfigValues = 2; + string buildOutput = 3; + repeated NixModuleConfigModuleEntry modulesV2 = 4; +} message NixModulesBuildRequest {} @@ -1171,6 +1238,10 @@ message NixModulesGetRegistryResponse { repeated NixModulesRegistryEntry modules = 1; map autoUpgrade = 2; map recommendUpgrade = 3; + repeated LanguageServerOption languageServers = 4; + repeated FormatterOption formatters = 5; + repeated PackagerOption packagers = 6; + repeated NixModulesV2RegistryEntry modulesV2 = 7; } message NixModulesRegistryEntry { @@ -1182,6 +1253,7 @@ message NixModulesRegistryEntry { repeated string tags = 6; string commit = 7; string path = 8; + string displayVersion = 9; } message NixModulesUpgradeMapEntry { @@ -1189,6 +1261,92 @@ message NixModulesUpgradeMapEntry { string changelog = 2; } +message NixModulesV2RegistryEntry { + string id = 1; + string name = 2; + string description = 3; + repeated NixModuleOption options = 4; +} + +message NixModuleOption { + string name = 1; + string description = 2; + oneof type { + NixModuleBooleanType booleanType = 3; + NixModuleStringType stringType = 4; + NixModuleChoiceStringType choiceStringType = 5; + NixModuleStringListType stringListType = 6; + NixModuleIntegerType integerType = 7; + } +} + +message NixModuleBooleanType { bool default = 1; } + +message NixModuleStringType { string default = 1; } + +message NixModuleIntegerType { int32 default = 1; } + +message NixModuleChoiceStringType { + string default = 1; + repeated string choices = 2; +} + +message NixModuleStringListType { repeated string default = 1; } + +message NixModuleConfigGetRequest {} + +message NixModuleConfigGetResponse { + repeated NixModuleConfigValue values = 1; + repeated NixModuleConfigModuleEntry modules = 2; +} + +message NixModuleConfigSetRequest { + repeated NixModuleConfigValue values = 1; + repeated NixModuleConfigModuleEntry modules = 2; +} + +message NixModuleConfigSetResponse { + enum Status { + Ok = 0; + Error = 1; + } + + NixModuleConfigSetResponse.Status status = 1; + string error = 2; +} + +message NixModuleConfigModuleEntry { + string id = 1; + repeated NixModuleConfigValue values = 2; +} + +message NixModuleConfigValue { + string moduleId = 1; + string optionName = 2; + oneof value { + string stringValue = 3; + int32 integerValue = 4; + bool booleanValue = 5; + StringList stringListValue = 7; + } +} + +message ReplspaceApiSSHTokenGetRequest { + string nonce = 1; + string replid = 2; +} + +message ReplspaceApiSSHTokenGetResponse { + string nonce = 1; + string token = 2; +} + +message StringList { repeated string stringList = 1; } + +message ObjectStorageConfig { string defaultBucketID = 1; } + +message AutoSaveConfig { bool disabled = 1; } + message ToolchainGetRequest {} message ToolchainConfigs { @@ -1230,6 +1388,8 @@ message LanguageServerOption { string language = 3; FileTypeAttrs fileTypeAttrs = 4; LanguageServerConfig config = 5; + string moduleId = 6; + string displayVersion = 7; } message FileTypeAttrs { @@ -1246,6 +1406,8 @@ message PackagerOption { bool enabledForHosting = 5; bool packageSearch = 6; bool guessImports = 7; + string moduleId = 8; + string displayVersion = 9; } message FormatterOption { @@ -1253,6 +1415,8 @@ message FormatterOption { string name = 2; Exec startCommand = 3; FileTypeAttrs fileTypeAttrs = 4; + string moduleId = 5; + string displayVersion = 6; } message ReplDomainDoubleDash { @@ -1277,6 +1441,14 @@ message ReplDomainId { string suffix = 2; } +message ReplDomainReplitDev { + string id = 1; + string version = 2; + string signature = 3; + string clusterName = 4; + string suffix = 5; +} + message ReplDomain { oneof kind { string custom = 1; @@ -1284,6 +1456,7 @@ message ReplDomain { ReplDomainDoubleDash doubleDash = 3; ReplDomainDots dots = 4; ReplDomainSingleDomain singleDomain = 5; + ReplDomainReplitDev replitDev = 6; } } @@ -1295,6 +1468,7 @@ message OutputBlockStartEvent { OutputBlockStartEvent.ExecutionMode executionMode = 1; google.protobuf.Timestamp measureStartTime = 2; + string cgroup = 3; } message OutputBlockEndEvent { @@ -1302,6 +1476,8 @@ message OutputBlockEndEvent { google.protobuf.Timestamp measureEndTime = 2; } +message ShellMetadata { string cgroup = 1; } + message RulesConfig { FormatterRules formatter = 1; } message FormatterRules { @@ -1317,48 +1493,6 @@ message FormatterConfigWithPattern { string pattern = 2; } -message ReplToken { - message ClassroomMetadata { - string id = 1; - string language = 2; - } - - message ReplID { - string id = 1; - string sourceRepl = 2; - } - - enum WireFormat { - PROTOBUF = 0; - JSON = 1; - PID2 = 2; - } - - message Presenced { - uint32 bearerID = 1; - string bearerName = 2; - } - - google.protobuf.Timestamp iat = 1; - google.protobuf.Timestamp exp = 2; - string salt = 3; - string cluster = 4; - repl.Persistence persistence = 6; - repl.ResourceLimits resourceLimits = 10; - repl.ResourceLimits interactiveResourceLimits = 17; - ReplToken.WireFormat format = 12; - ReplToken.Presenced presenced = 13; - repeated string flags = 14; - repl.Permissions permissions = 15; - repeated features.Feature features = 16; - repl.BuildInfo buildInfo = 18; - oneof metadata { - repl.Repl repl = 7; - ReplToken.ReplID id = 8; - ReplToken.ClassroomMetadata classroom = 9; - } -} - message TLSCertificate { string domain = 1; bytes cert = 2; @@ -1446,7 +1580,7 @@ message GovalToken { google.protobuf.Timestamp exp = 2; string replid = 3; oneof Token { - ReplToken replToken = 4; + token.ReplToken replToken = 4; GovalReplIdentity replIdentity = 5; } } @@ -1462,6 +1596,7 @@ message GovalReplIdentity { repl.BuildInfo buildInfo = 8; bool isTeam = 9; repeated string roles = 10; + repl.Org org = 14; oneof runtime { ReplRuntimeInteractive interactive = 11; ReplRuntimeHosting hosting = 13; @@ -1481,6 +1616,51 @@ message ReplRuntimeHosting { message ReplRuntimeDeployment {} +message token { + message ReplToken { + message ClassroomMetadata { + string id = 1; + string language = 2; + } + + message ReplID { + string id = 1; + string sourceRepl = 2; + } + + enum WireFormat { + PROTOBUF = 0; + JSON = 1; + PID2 = 2; + } + + message Presenced { + uint32 bearerID = 1; + string bearerName = 2; + } + + google.protobuf.Timestamp iat = 1; + google.protobuf.Timestamp exp = 2; + string salt = 3; + string cluster = 4; + repl.Persistence persistence = 6; + repl.ResourceLimits resourceLimits = 10; + repl.ResourceLimits interactiveResourceLimits = 17; + token.ReplToken.WireFormat format = 12; + token.ReplToken.Presenced presenced = 13; + repeated string flags = 14; + repeated features.Feature features = 16; + repl.BuildInfo buildInfo = 18; + repl.Pid2Binary pid2Info = 19; + bool paid = 20; + oneof metadata { + repl.Repl repl = 7; + token.ReplToken.ReplID id = 8; + token.ReplToken.ClassroomMetadata classroom = 9; + } + } +} + message lore { message LoreCommand { oneof command { @@ -1496,6 +1676,7 @@ message lore { message ClusterTransfer { string replId = 1; string user = 2; + lore.ReplLocation replLocation = 6; string transferId = 4; oneof location { string newClusterId = 3; @@ -1545,6 +1726,176 @@ message lore { string replId = 1; repeated string flags = 2; } + + message Buckets { + string files = 1; + string snapshots = 2; + string metadata = 3; + string diskBlocks = 4; + } + + message Repl { + string id = 1; + string user = 2; + string slug = 3; + } + + message Cluster { + string name = 1; + string conmanUrl = 2; + string gurl = 3; + string proxy = 4; + } + + message CreateReplRequest { + message Repl { + string id = 1; + string user = 2; + string slug = 3; + } + + message File { + string name = 1; + bytes contents = 2; + } + + message SourceFiles { repeated lore.CreateReplRequest.File files = 1; } + + message Buckets { + string files = 1; + string snapshots = 2; + } + + message SourceRepl { + string id = 1; + bool requireSnapshot = 2; + lore.CreateReplRequest.Buckets buckets = 3; + } + + lore.CreateReplRequest.Repl repl = 1; + lore.ReplLocation replLocation = 7; + string overrideFilesBucket = 5; + oneof location { + string cluster = 2; + string continent = 6; + } + oneof source { + lore.CreateReplRequest.SourceRepl sourceRepl = 3; + lore.CreateReplRequest.SourceFiles sourceFiles = 4; + } + } + + message CreateReplResponse {} + + message GetReplRequest { string replId = 1; } + + message GetReplResponse { + lore.Repl repl = 1; + lore.Cluster cluster = 2; + lore.Buckets buckets = 3; + string dotdevHostname = 4; + } + + message ReplLocation { + bool regionalGoval = 3; + oneof location { + string cluster = 1; + string continent = 2; + } + } + + message GetReplConnectionInfoRequest { + string replId = 1; + string slug = 2; + string user = 3; + bool persistent = 4; + lore.ReplLocation replLocation = 9; + string sourceReplId = 7; + oneof defaultLocation { + string defaultCluster = 5; + string defaultContinent = 8; + } + } + + message GetReplConnectionInfoResponse { + lore.Repl repl = 1; + lore.Cluster cluster = 2; + lore.Buckets buckets = 3; + string dotdevHostname = 4; + } + + message GetTransferStatusRequest { string transferId = 1; } + + message GetTransferStatusResponse { + string transferId = 1; + bool complete = 2; + } + + message TransferReplsRequest { + string newCluster = 1; + repeated string replIds = 2; + lore.ReplLocation newLocation = 3; + } + + message TransferReplsResponse { string transferId = 1; } + + message TransferReplFromOfflineClusterRequest { + string newCluster = 1; + string replId = 2; + } + + message TransferReplFromOfflineClusterResponse {} + + message TransferUserRequest { + string user = 1; + string newCluster = 2; + repeated string excludedReplIds = 3; + } + + message TransferUserResponse { string transferId = 1; } + + message Continent { + string code = 1; + string name = 2; + } + + message TakedownReplRequest { string replId = 1; } + + message TakedownReplResponse {} + + message SoftTakedownReplRequest { string replId = 1; } + + message SoftTakedownReplResponse {} + + message RestoreReplRequest { string replId = 1; } + + message RestoreReplResponse {} + + message BulkRemoveRequest { repeated string replIds = 1; } + + message BulkRemoveResponse {} + + message GetClustersRequest {} + + message GetClustersResponse { repeated lore.Cluster clusters = 1; } + + message PushDomainRequest { + string replId = 1; + string domain = 2; + string authToken = 3; + } + + message PushDomainResponse {} + + message UnlinkDomainRequest { + string replId = 1; + string domain = 2; + string authToken = 3; + } + + message UnlinkDomainResponse {} + + message Lore {} } message features { @@ -1577,6 +1928,7 @@ message repl { string bucket = 3; string slug = 4; string user = 5; + repl.Org org = 14; string sourceRepl = 6; string database = 7; repl.Buckets buckets = 8; @@ -1586,6 +1938,17 @@ message repl { string logFields = 13; } + message Org { + enum OrgType { + TYPE_UNSPECIFIED = 0; + PERSONAL = 1; + TEAM = 2; + } + + string id = 1; + repl.Org.OrgType type = 2; + } + enum Environment { DEVELOPMENT = 0; PRODUCTION = 1; @@ -1612,11 +1975,8 @@ message repl { int64 scratchDisk = 9; repl.ResourceLimits.Cachability cache = 6; bool restrictNetwork = 7; - bool preventWakeup = 8; } - message Permissions { bool toggleAlwaysOn = 1; } - enum Persistence { PERSISTENT = 0; EPHEMERAL = 1; @@ -1630,7 +1990,6 @@ message repl { repl.ResourceLimits interactiveResourceLimits = 17; repl.Persistence persistence = 6; repeated string flags = 14; - repl.Permissions permissions = 15; repeated features.Feature features = 16; repl.BuildInfo buildInfo = 18; } @@ -1641,6 +2000,8 @@ message repl { string buildId = 3; string machineTier = 4; } + + message Pid2Binary { string version = 1; } } message PrivateReplsPowerup { bool enabled = 1; } diff --git a/services/src/fsevents.rs b/services/src/fsevents.rs new file mode 100644 index 0000000..b931259 --- /dev/null +++ b/services/src/fsevents.rs @@ -0,0 +1,130 @@ +pub struct FSEvents { + // watching: Vec + watcher: FSWatcher, +} + +use super::traits; +use crate::{FSEvent, FSWatcher}; +use anyhow::{format_err, Result}; +use goval::{Command, File, FileEvent}; +use tracing::{error, trace, warn}; + +impl FSEvents { + pub async fn new( + sender: tokio::sync::mpsc::UnboundedSender, + ) -> Result { + let watcher = FSWatcher::new(sender).await?; + + let chan = FSEvents { + // watching: vec![], + watcher, + }; + + Ok(chan) + } +} + +#[async_trait::async_trait] +impl traits::Service for FSEvents { + async fn open(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { + Ok(()) + } + + async fn message( + &mut self, + _info: &super::types::ChannelInfo, + message: goval::Command, + _session: i32, + ) -> Result> { + let body = match message.body.clone() { + None => return Err(format_err!("Expected command body")), + Some(body) => body, + }; + + match body { + goval::command::Body::SubscribeFile(subscribe) => { + let mut files = vec![]; + for file in subscribe.files { + files.push(file.path); + } + + self.watcher.watch(files).await?; + Ok(Some(goval::Command { + body: Some(goval::command::Body::Ok(goval::Ok {})), + ..Default::default() + })) + } + _ => { + warn!(cmd = ?message, "Unknown fs event command"); + Ok(None) + } + } + } + + async fn fsevent(&mut self, info: &super::types::ChannelInfo, event: FSEvent) -> Result<()> { + trace!(?event, "fs event"); + let file; + let dest; + let op; + match event { + FSEvent::Modify(path) => { + file = Some(File { + path, + ..Default::default() + }); + dest = None; + op = goval::file_event::Op::Modify; + } + FSEvent::Create(path) => { + file = Some(File { + path, + ..Default::default() + }); + dest = None; + op = goval::file_event::Op::Create; + } + FSEvent::Remove(path) => { + file = Some(File { + path, + ..Default::default() + }); + dest = None; + op = goval::file_event::Op::Remove; + } + FSEvent::Rename(old_path, new_path) => { + file = Some(File { + path: new_path, + ..Default::default() + }); + dest = Some(File { + path: old_path, + ..Default::default() + }); + op = goval::file_event::Op::Move; + } + FSEvent::Err(err) => { + error!(err, "Error in FS event listener"); + return Err(format_err!("{err}")); + } + }; + + info.send( + Command { + body: Some(goval::command::Body::FileEvent(FileEvent { + file, + dest, + op: op.into(), + })), + ..Default::default() + }, + crate::SendSessions::Everyone, + ) + .await?; + Ok(()) + } + + async fn shutdown(self: Box, _info: &super::types::ChannelInfo) -> Result<()> { + self.watcher.shutdown().await; + Ok(()) + } +} diff --git a/services/src/lib.rs b/services/src/lib.rs index 4dbba9b..6c9bdd5 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -1,6 +1,7 @@ mod chat; mod dotreplit; mod exec; +mod fsevents; mod gcsfiles; mod git; mod ot; @@ -57,8 +58,10 @@ impl Channel { "git" => Box::new(git::Git::new()), "exec" => Box::new(exec::Exec::new()), "dotreplit" => Box::new(dotreplit::DotReplit {}), - "null" => Box::new(stub::Stub {}), // This channel never does anything - "open" => Box::new(stub::Stub {}), // Stub until infra is set up to handle this + "fsevents" => Box::new(fsevents::FSEvents::new(sender).await?), + "audio" => Box::new(stub::Stub {}), // Will never be supported + "null" => Box::new(stub::Stub {}), // This channel never does anything + "open" => Box::new(stub::Stub {}), // Stub until infra is set up to handle this _ => return Err(format_err!("Unknown service: {}", service)), }; @@ -159,10 +162,11 @@ pub static IMPLEMENTED_SERVICES: &[&str] = &[ "snapshot", "null", "git", - "open", + "audio", "output", "shell", "toolchain", "dotreplit", "exec", + "fsevents", ]; diff --git a/services/src/output.rs b/services/src/output.rs index a56c92f..2ecd19e 100644 --- a/services/src/output.rs +++ b/services/src/output.rs @@ -37,6 +37,7 @@ impl traits::Service for Output { seconds: self.start_time.unwrap_or(0), nanos: 0, }), + ..Default::default() }; new_frame.body = Some(goval::command::Body::OutputBlockStartEvent(event)); @@ -112,6 +113,7 @@ impl traits::Service for Output { seconds: now, nanos: 0, }), + ..Default::default() }; new_frame.body = Some(goval::command::Body::OutputBlockStartEvent(event)); diff --git a/services/src/stub.rs b/services/src/stub.rs index b19fdc2..7fbcd32 100644 --- a/services/src/stub.rs +++ b/services/src/stub.rs @@ -1,4 +1,5 @@ pub struct Stub {} use super::traits; +// #[async_trait::async_trait] impl traits::Service for Stub {} diff --git a/src/parse_paseto.rs b/src/parse_paseto.rs index a9042c1..975b484 100644 --- a/src/parse_paseto.rs +++ b/src/parse_paseto.rs @@ -150,7 +150,7 @@ pub async fn parse(token: &str) -> Result { } let _inner = general_purpose::STANDARD.decode(msg)?; - let inner = goval::ReplToken::decode(_inner.as_slice())?; + let inner = goval::token::ReplToken::decode(_inner.as_slice())?; match inner.presenced { Some(user) => Ok(ClientInfo { From 7ec567fedb4c52dbf7a7aa2c6da22e8d128cf9c8 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 13 Apr 2024 09:55:33 -0700 Subject: [PATCH 076/103] docs: Update readme and remove all references to js --- README.md | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index d014f4a..27fafb8 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ > [!CAUTION] -> **⚠️ Homeval is still in early alpha and can be unstable so do not trust it with data you have not backed up. ⚠️** +> Homeval is still in early alpha and can be unstable so do not trust it with data you have not backed up. # License Homeval is licensed under GNU AGPL-3.0-only @@ -45,22 +45,22 @@ If the database isn't setup repldb won't work, and file history won't persist th ### Proper Authentication > [!WARNING] -> ⚠If you use someone else's key server it could let them authenticate as any user on your homeval instance +> If you use someone else's key server it could let them authenticate as any user on your homeval instance + +> [!NOTE] +> This feature has not been tested with deployments yet, a new solution may be needed. Run [repl-key-server](https://github.com/Goval-Community/repl-key-server) on a repl and set the env var `$HOMEVAL_PASETO_KEY_URL` to `/keys`. ### Replspace api > [!IMPORTANT] -> This will not work on windows. +> This will not work on windows see #112 To make use of this feature make sure that all files in `extras/` are placed in a directory contained in your `$PATH` on the machine running homeval. -## ⚠️ Notice for windows users -On windows `cargo run` as well as invoking the built binary must happen inside the [Git Bash](https://gitforwindows.org/) shell. - ## Building -Homeval can be built into a binary with `cargo build --release` the binary will then end up in `target/release/homeval` (make sure to set `RUST_LOG=INFO` when running this binary or you won't get any logs). +Homeval can be built into a binary with `cargo build --release` the binary will then end up in `target/release/homeval` or `target/release/homeval.exe` (make sure to set `RUST_LOG=INFO` when running this binary or you won't get any logs). ### Minimal Build To build a minimal build run `cargo build --release --no-default-features`, this will compile out the following features: @@ -77,9 +77,12 @@ To compile and run a debug build use `cargo run`. # Implementing a service -Make a new file in `services/` name it with the format `.js` then see existing services and `src/runtime.js` for the interface you need to provide. Docs focussed on implementing services are a WIP. +Make a new file in `services/src/` name it with the format `.rs` then see existing services and `services/src/traits.rs` for the interface you need to provide. Docs focussed on implementing services are a WIP. -> NOTE: The source code for services are compiled in to release builds, but loaded at runtime for debug builds. +To then use the service you will need to edit `services/src/lib.rs` to include your service. +1) Make a new line at the top of `services/src/lib.rs` and add `mod ` +2) Go to the definition of [`Channel::new`](https://github.com/search?q=repo%3AGoval-Community%2Fhomeval%20Channel%3A%3Anew&type=code) and add your service initialization code to the match statement. +3) Add your service to `IMPLEMENTED_SERVICES` (it can be found at the bottom of `services/src/lib.rs`) # Supported targets @@ -88,7 +91,7 @@ Make a new file in `services/` name it with the format `.js` then | --- | --- | --- | --- | --- | | Linux[^linux] | ✅ | ✅ | ✅ | ✅[^linux-tests] | | macOS[^macos] | ✅ | ✅ | ✅ | ❎ | -| Windows | ✅ | ✅ | ✅ | ❎ | +| Windows | ✅ | ✅ | ✅[^windows] | ❎ | [^testing]: This marks if every release is officially tested for this target. @@ -99,8 +102,4 @@ Make a new file in `services/` name it with the format `.js` then [^linux-tests]: Currently, the only tested distribution is arch linux. Though all distros with an up to date GLIC *should* work. -# TODO: - -- [ ] Debugger support -- [ ] Pid2 Support -- [ ] Unit Tests \ No newline at end of file +[^windows]: While the windows binary supports every feature, the replspace binaries found in [extras](extras/) still need to be ported to batch/powershell (#112) \ No newline at end of file From f80679953ec01673019f171b1b6ebea30983c955 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 13 Apr 2024 10:28:33 -0700 Subject: [PATCH 077/103] refactor: Fix all clippy warnings - Make gcsfiles#write truncate the file - Use clone_from when applicable - Actually use `Service::open` - Let services access base env vars - Remove unused statics - Move statics only used in `goval_server.rs` to `goval_server.rs` --- services/src/chat.rs | 4 --- services/src/exec.rs | 2 -- services/src/fsevents.rs | 4 --- services/src/gcsfiles.rs | 1 + services/src/lib.rs | 13 +++++---- services/src/ot.rs | 6 +--- services/src/output.rs | 2 +- services/src/presence.rs | 6 +--- services/src/traits.rs | 1 + services/src/types/channel_info.rs | 2 +- services/src/types/messaging.rs | 2 -- services/src/types/proc.rs | 15 +++++----- services/src/types/pty.rs | 35 +++++++++++----------- src/goval_server.rs | 47 +++++++++++++----------------- src/main.rs | 30 ++----------------- 15 files changed, 62 insertions(+), 108 deletions(-) diff --git a/services/src/chat.rs b/services/src/chat.rs index 7a72b5b..b8abf55 100644 --- a/services/src/chat.rs +++ b/services/src/chat.rs @@ -17,10 +17,6 @@ impl Chat { #[async_trait] impl traits::Service for Chat { - async fn open(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { - Ok(()) - } - async fn message( &mut self, info: &super::types::ChannelInfo, diff --git a/services/src/exec.rs b/services/src/exec.rs index 56d9902..8cd0bb9 100644 --- a/services/src/exec.rs +++ b/services/src/exec.rs @@ -4,8 +4,6 @@ pub struct Exec { current_ref: String, } -use std::collections::HashMap; - use crate::Proc; use super::traits; diff --git a/services/src/fsevents.rs b/services/src/fsevents.rs index b931259..fe3f2ff 100644 --- a/services/src/fsevents.rs +++ b/services/src/fsevents.rs @@ -26,10 +26,6 @@ impl FSEvents { #[async_trait::async_trait] impl traits::Service for FSEvents { - async fn open(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { - Ok(()) - } - async fn message( &mut self, _info: &super::types::ChannelInfo, diff --git a/services/src/gcsfiles.rs b/services/src/gcsfiles.rs index 062a941..0249271 100644 --- a/services/src/gcsfiles.rs +++ b/services/src/gcsfiles.rs @@ -138,6 +138,7 @@ impl traits::Service for GCSFiles { let mut file = fs::OpenOptions::new() .write(true) .create(true) + .truncate(true) .open(_file.path) .await?; file.set_len(0).await?; diff --git a/services/src/lib.rs b/services/src/lib.rs index 6c9bdd5..6ecf37a 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -34,6 +34,7 @@ impl Channel { service: String, name: Option, dotreplit: Arc>, + child_env_vars: Arc>>, sender: tokio::sync::mpsc::UnboundedSender, ) -> Result { let info = ChannelInfo { @@ -44,6 +45,7 @@ impl Channel { sessions: HashMap::new(), sender: sender.clone(), dotreplit, + child_env_vars, }; let channel: Box = match service.as_str() { @@ -72,6 +74,10 @@ impl Channel { } pub async fn start(mut self, mut read: tokio::sync::mpsc::UnboundedReceiver) { + if let Err(err) = self._inner.open(&self.info).await { + error!(%err, "Error encountered in Service::open"); + } + while let Some(message) = read.recv().await { let result = match message { ChannelMessage::Attach(session, client, sender) => { @@ -100,11 +106,8 @@ impl Channel { } }; - match result { - Ok(_) => {} - Err(err) => { - error!(%err, "Error encountered in service") - } + if let Err(err) = result { + error!(%err, "Error encountered in service"); } } } diff --git a/services/src/ot.rs b/services/src/ot.rs index dc83b23..361fead 100644 --- a/services/src/ot.rs +++ b/services/src/ot.rs @@ -44,10 +44,6 @@ impl OT { #[async_trait] impl traits::Service for OT { - async fn open(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { - Ok(()) - } - async fn message( &mut self, info: &super::types::ChannelInfo, @@ -73,7 +69,7 @@ impl traits::Service for OT { return Ok(Some(error)); } - self.path = path.clone(); + self.path.clone_from(&path); let byte_contents = fs::read(path.clone()).await?; let crc32 = crc32fast::hash(byte_contents.as_slice()); diff --git a/services/src/output.rs b/services/src/output.rs index 2ecd19e..9054426 100644 --- a/services/src/output.rs +++ b/services/src/output.rs @@ -87,7 +87,7 @@ impl traits::Service for Output { ]; if let Some(run) = &info.dotreplit.read().await.run { if let Some(args) = &run.args { - cmd = args.clone() + cmd.clone_from(args); } } diff --git a/services/src/presence.rs b/services/src/presence.rs index 6a703cc..3cdd0ad 100644 --- a/services/src/presence.rs +++ b/services/src/presence.rs @@ -24,10 +24,6 @@ impl Presence { #[async_trait] impl traits::Service for Presence { - async fn open(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { - Ok(()) - } - async fn message( &mut self, info: &super::types::ChannelInfo, @@ -115,7 +111,7 @@ impl traits::Service for Presence { } _inner.files = files; - _inner.user = self.users.clone(); + _inner.user.clone_from(&self.users); roster.body = Some(goval::command::Body::Roster(_inner)); let user = goval::User { diff --git a/services/src/traits.rs b/services/src/traits.rs index 9db0464..a3ae67c 100644 --- a/services/src/traits.rs +++ b/services/src/traits.rs @@ -9,6 +9,7 @@ pub(crate) trait Service { async fn open(&mut self, _info: &super::types::ChannelInfo) -> Result<()> { Ok(()) } + async fn shutdown(self: Box, _info: &super::types::ChannelInfo) -> Result<()> { Ok(()) } diff --git a/services/src/types/channel_info.rs b/services/src/types/channel_info.rs index 70499df..3b51ab9 100644 --- a/services/src/types/channel_info.rs +++ b/services/src/types/channel_info.rs @@ -2,7 +2,6 @@ use std::collections::HashMap; use std::sync::Arc; use anyhow::Result; -use goval; use tokio::sync::RwLock; use tracing::error; @@ -26,6 +25,7 @@ pub struct ChannelInfo { pub sessions: HashMap, pub sender: tokio::sync::mpsc::UnboundedSender, pub dotreplit: Arc>, + pub child_env_vars: Arc>>, } impl ChannelInfo { diff --git a/services/src/types/messaging.rs b/services/src/types/messaging.rs index e8c1502..5c90f9f 100644 --- a/services/src/types/messaging.rs +++ b/services/src/types/messaging.rs @@ -1,7 +1,5 @@ use anyhow::Result; -use goval; use prost::Message; -use serde; use serde::{Deserialize, Serialize}; use tokio::sync::mpsc::Sender; diff --git a/services/src/types/proc.rs b/services/src/types/proc.rs index bedfea1..75d6080 100644 --- a/services/src/types/proc.rs +++ b/services/src/types/proc.rs @@ -1,17 +1,16 @@ use std::{ collections::{HashMap, VecDeque}, pin::Pin, - process::{ExitStatus, Stdio}, + process::Stdio, sync::{atomic::AtomicBool, Arc}, task::{Context, Poll}, }; -use crate::{ChannelMessage, IPCMessage, SendSessions}; +use crate::{ChannelMessage, SendSessions}; use anyhow::Result; use tokio::{ - io::{AsyncReadExt, AsyncWrite, AsyncWriteExt, ReadBuf}, + io::{AsyncWrite, AsyncWriteExt}, process::ChildStdin, - sync::RwLock, }; use tracing::{error, trace}; @@ -80,9 +79,9 @@ impl AsyncWrite for CmdWriter { } pub struct Proc { - channel: i32, + _channel: i32, cancelled: Arc, - contact: tokio::sync::mpsc::UnboundedSender, + _contact: tokio::sync::mpsc::UnboundedSender, stdin: ChildStdin, } @@ -173,8 +172,8 @@ impl Proc { }); Ok(Proc { - channel, - contact, + _channel: channel, + _contact: contact, cancelled, stdin, }) diff --git a/services/src/types/pty.rs b/services/src/types/pty.rs index 04bb666..7749ea0 100644 --- a/services/src/types/pty.rs +++ b/services/src/types/pty.rs @@ -106,10 +106,7 @@ impl Pty { contact: tokio::sync::mpsc::UnboundedSender, _env: Option>, ) -> Result { - let env = match _env { - Some(env) => env, - None => HashMap::new(), - }; + let env = _env.unwrap_or_default(); let pty_system = portable_pty::native_pty_system(); @@ -173,21 +170,23 @@ impl Pty { }); let child_lock_reaper = child_lock.clone(); - tokio::task::spawn(async move { - match tokio::task::spawn(async move { - let mut interval = tokio::time::interval(Duration::from_millis(50)); - - loop { - interval.tick().await; - let mut child_ = child_lock_reaper.lock().await; - if let Some(exit_code) = child_.try_wait()? { - return Ok::(exit_code.exit_code() as i32); - } - drop(child_); + + let task_res = tokio::task::spawn(async move { + let mut interval = tokio::time::interval(Duration::from_millis(50)); + + loop { + interval.tick().await; + let mut child_ = child_lock_reaper.lock().await; + if let Some(exit_code) = child_.try_wait()? { + return Ok::(exit_code.exit_code() as i32); } - }) - .await - { + drop(child_); + } + }) + .await; + + tokio::task::spawn(async move { + match task_res { Ok(res) => { match res { Ok(exit_code) => { diff --git a/src/goval_server.rs b/src/goval_server.rs index 90763b4..fc5b5c6 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -15,19 +15,31 @@ use anyhow::Result; use goval::{Command, OpenChannel}; use homeval_services::{ClientInfo, ServiceMetadata}; use prost::Message; -use std::{net::SocketAddr, sync::LazyLock}; -use tokio::sync::{mpsc::UnboundedSender, Mutex}; +use std::{collections::HashMap, net::SocketAddr, sync::LazyLock}; +use tokio::sync::{mpsc::UnboundedSender, Mutex, RwLock}; use futures_util::{SinkExt, StreamExt}; use tokio::sync::mpsc; use tracing::{debug, error, info, trace, warn}; use crate::{ - CHANNEL_MESSAGES, CHANNEL_METADATA, CHANNEL_SESSIONS, LAST_SESSION_USING_CHANNEL, MAX_SESSION, - PROCCESS_CHANNEL_TO_ID, SESSION_CHANNELS, SESSION_CLIENT_INFO, SESSION_MAP, + parse_paseto::parse, ChannelMessage, IPCMessage, CHANNEL_MESSAGES, CHILD_PROCS_ENV_BASE, + DOTREPLIT_CONFIG, LAST_SESSION_USING_CHANNEL, }; -use crate::{parse_paseto::parse, ChannelMessage, IPCMessage}; +static MAX_SESSION: LazyLock> = LazyLock::new(|| Mutex::new(0)); + +static SESSION_CHANNELS: LazyLock>>> = + LazyLock::new(|| RwLock::new(HashMap::new())); +static SESSION_CLIENT_INFO: LazyLock>> = + LazyLock::new(|| RwLock::new(HashMap::new())); + +static CHANNEL_METADATA: LazyLock>> = + LazyLock::new(|| RwLock::new(HashMap::new())); +static CHANNEL_SESSIONS: LazyLock>>> = + LazyLock::new(|| RwLock::new(HashMap::new())); +static SESSION_MAP: LazyLock>>> = + LazyLock::new(|| RwLock::new(HashMap::new())); #[derive(Clone)] struct AppState { @@ -173,23 +185,6 @@ async fn handle_message( _ => {} } } else { - // Directly deal with Command::Input, should be faster - if let goval::command::Body::Input(input) = cmd_body { - if let Some(pty_id) = PROCCESS_CHANNEL_TO_ID.read().await.get(&cmd.channel) { - let mut to_continue = false; - if let Some(queue) = crate::PROCCESS_WRITE_MESSAGES.read().await.get(pty_id) { - queue.push(input); - to_continue = true; - } else { - error!(pty_id, "Couldn't find pty to write to"); - } - - if to_continue { - return; - } - } - } - let msg_lock = CHANNEL_MESSAGES.read().await; let queue = msg_lock.get(&cmd.channel).unwrap().clone(); @@ -281,7 +276,8 @@ async fn open_channel( channel_id, service, _channel_name, - crate::DOTREPLIT_CONFIG.clone(), + DOTREPLIT_CONFIG.clone(), + CHILD_PROCS_ENV_BASE.clone(), writer, ) .await @@ -299,7 +295,7 @@ async fn open_channel( }; protocol_error.body = Some(goval::command::Body::ProtocolError(_inner)); - protocol_error.r#ref = message.command.r#ref.clone(); + protocol_error.r#ref.clone_from(&message.command.r#ref); protocol_error.channel = 0; session_map @@ -320,7 +316,7 @@ async fn open_channel( }; open_chan_res.body = Some(goval::command::Body::OpenChanRes(_open_res)); - open_chan_res.r#ref = message.command.r#ref.clone(); + open_chan_res.r#ref.clone_from(&message.command.r#ref); open_chan_res.channel = 0; session_map @@ -412,7 +408,6 @@ async fn detach_channel(channel: i32, session: i32, forced: bool) -> Result<()> CHANNEL_METADATA.write().await.remove(&channel); CHANNEL_SESSIONS.write().await.remove(&channel); CHANNEL_MESSAGES.write().await.remove(&channel); - PROCCESS_CHANNEL_TO_ID.write().await.remove(&channel); LAST_SESSION_USING_CHANNEL.write().await.remove(&channel); }); } else { diff --git a/src/main.rs b/src/main.rs index 3bae15e..4fc4311 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,16 +4,14 @@ use std::sync::LazyLock; use std::time::Instant; use std::{collections::HashMap, io::Error, sync::Arc}; -use tokio::sync::{mpsc, Mutex, RwLock}; +use tokio::sync::RwLock; use tracing::{debug, info}; use homeval_services::{ config::dotreplit::DotReplit, messaging::ReplspaceMessage, ChannelMessage, - ClientInfo, IPCMessage, - ServiceMetadata, // ReplspaceMessage, }; @@ -29,37 +27,15 @@ pub static START_TIME: LazyLock = LazyLock::new(Instant::now); static CPU_STATS: LazyLock> = LazyLock::new(|| Arc::new(cpu_time::ProcessTime::now())); -pub static IMPLEMENTED_SERVICES: LazyLock> = LazyLock::new(Vec::new); - pub static DOTREPLIT_CONFIG: LazyLock>> = LazyLock::new(|| { Arc::new(RwLock::const_new( toml::from_str(&std::fs::read_to_string(".replit").unwrap_or("".to_string())).unwrap(), )) }); -static MAX_SESSION: LazyLock> = LazyLock::new(|| Mutex::new(0)); - -static SESSION_CHANNELS: LazyLock>>> = - LazyLock::new(|| RwLock::new(HashMap::new())); -static SESSION_CLIENT_INFO: LazyLock>> = - LazyLock::new(|| RwLock::new(HashMap::new())); static CHANNEL_MESSAGES: LazyLock< RwLock>>, > = LazyLock::new(|| RwLock::new(HashMap::new())); -static CHANNEL_METADATA: LazyLock>> = - LazyLock::new(|| RwLock::new(HashMap::new())); -static CHANNEL_SESSIONS: LazyLock>>> = - LazyLock::new(|| RwLock::new(HashMap::new())); -static SESSION_MAP: LazyLock>>> = - LazyLock::new(|| RwLock::new(HashMap::new())); - -// pty and cmd's -static PROCCESS_WRITE_MESSAGES: LazyLock< - RwLock>>>, -> = LazyLock::new(|| RwLock::new(HashMap::new())); -static PROCCESS_CHANNEL_TO_ID: LazyLock>> = - LazyLock::new(|| RwLock::new(HashMap::new())); - // Hashmap for channel id -> last session that sent it a message static LAST_SESSION_USING_CHANNEL: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); @@ -68,8 +44,8 @@ static LAST_SESSION_USING_CHANNEL: LazyLock>> = // RwLock>>>, // > = LazyLock::new(|| RwLock::new(HashMap::new())); -static CHILD_PROCS_ENV_BASE: LazyLock>> = - LazyLock::new(|| RwLock::new(HashMap::new())); +static CHILD_PROCS_ENV_BASE: LazyLock>>> = + LazyLock::new(|| Arc::new(RwLock::new(HashMap::new()))); #[cfg(feature = "database")] mod database; From 42dd05146ffe0e4085aa872b9bfff28eb5af3e47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 13 Apr 2024 23:37:39 +0000 Subject: [PATCH 078/103] build(deps): bump serde from 1.0.196 to 1.0.197 Bumps [serde](https://github.com/serde-rs/serde) from 1.0.196 to 1.0.197. - [Release notes](https://github.com/serde-rs/serde/releases) - [Commits](https://github.com/serde-rs/serde/compare/v1.0.196...v1.0.197) --- updated-dependencies: - dependency-name: serde dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- Cargo.toml | 2 +- entity/Cargo.toml | 2 +- services/Cargo.toml | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a6ec40..52b4cfc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2655,18 +2655,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 116dcdc..5846c0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } prost = "0.12.3" prost-types = "0.12.3" serde_json = "1.0.115" -serde = { version = "1.0.196", features = ["derive"] } +serde = { version = "1.0.197", features = ["derive"] } tokio = {version="1.36.0", features = ["full"]} base64 = "0.21.0" futures = "0.3.28" diff --git a/entity/Cargo.toml b/entity/Cargo.toml index 07922a5..1e7766d 100644 --- a/entity/Cargo.toml +++ b/entity/Cargo.toml @@ -10,4 +10,4 @@ path = "src/mod.rs" [dependencies] sea-orm = "0.12.14" -serde = "1.0.196" +serde = "1.0.197" diff --git a/services/Cargo.toml b/services/Cargo.toml index 0afca45..79a02d5 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -17,7 +17,7 @@ portable-pty = "0.8.1" prost = "0.12.3" prost-types = "0.12.3" ropey = "1.6.0" -serde = "1.0.196" +serde = "1.0.197" serde_json = "1.0.115" similar = "2.2.1" tokio = "1.36.0" From 539a26f87465d4fb99cc8f7d42abd3ffe53ca815 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 13 Apr 2024 16:53:47 -0700 Subject: [PATCH 079/103] refactor: Use special new type for session ids instead of i32 --- services/src/chat.rs | 6 +- services/src/dotreplit.rs | 4 +- services/src/exec.rs | 4 +- services/src/fsevents.rs | 4 +- services/src/gcsfiles.rs | 4 +- services/src/git.rs | 8 +-- services/src/lib.rs | 6 +- services/src/ot.rs | 6 +- services/src/output.rs | 8 +-- services/src/presence.rs | 29 ++++---- services/src/shell.rs | 8 +-- services/src/snapshot.rs | 4 +- services/src/toolchain.rs | 4 +- services/src/traits.rs | 10 +-- services/src/types/channel_info.rs | 15 +++-- services/src/types/messaging.rs | 12 ++-- services/src/types/mod.rs | 3 + services/src/types/pty.rs | 16 ++--- services/src/types/session.rs | 33 +++++++++ src/goval_server.rs | 105 ++++++++++++++--------------- src/main.rs | 3 +- src/replspace_server.rs | 11 +-- 22 files changed, 173 insertions(+), 130 deletions(-) create mode 100644 services/src/types/session.rs diff --git a/services/src/chat.rs b/services/src/chat.rs index b8abf55..019059b 100644 --- a/services/src/chat.rs +++ b/services/src/chat.rs @@ -2,7 +2,7 @@ pub struct Chat { history: Vec, } -use crate::{ClientInfo, IPCMessage, SendSessions}; +use crate::{ClientInfo, IPCMessage, SendSessions, Session}; use super::traits; use anyhow::{format_err, Result}; @@ -21,7 +21,7 @@ impl traits::Service for Chat { &mut self, info: &super::types::ChannelInfo, message: goval::Command, - session: i32, + session: Session, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), @@ -51,7 +51,7 @@ impl traits::Service for Chat { &mut self, _info: &super::types::ChannelInfo, _client: ClientInfo, - _session: i32, + _session: Session, _sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { let mut scrollback = goval::Command::default(); diff --git a/services/src/dotreplit.rs b/services/src/dotreplit.rs index ae33cbb..0e96f98 100644 --- a/services/src/dotreplit.rs +++ b/services/src/dotreplit.rs @@ -1,4 +1,6 @@ pub struct DotReplit {} +use crate::Session; + use super::traits; use anyhow::{format_err, Result}; @@ -10,7 +12,7 @@ impl traits::Service for DotReplit { &mut self, _info: &super::types::ChannelInfo, message: goval::Command, - _session: i32, + _session: Session, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/exec.rs b/services/src/exec.rs index 8cd0bb9..6e32253 100644 --- a/services/src/exec.rs +++ b/services/src/exec.rs @@ -4,7 +4,7 @@ pub struct Exec { current_ref: String, } -use crate::Proc; +use crate::{Proc, Session}; use super::traits; use anyhow::{format_err, Result}; @@ -16,7 +16,7 @@ impl traits::Service for Exec { &mut self, info: &super::types::ChannelInfo, message: goval::Command, - _session: i32, + _session: Session, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/fsevents.rs b/services/src/fsevents.rs index fe3f2ff..86fc295 100644 --- a/services/src/fsevents.rs +++ b/services/src/fsevents.rs @@ -4,7 +4,7 @@ pub struct FSEvents { } use super::traits; -use crate::{FSEvent, FSWatcher}; +use crate::{FSEvent, FSWatcher, Session}; use anyhow::{format_err, Result}; use goval::{Command, File, FileEvent}; use tracing::{error, trace, warn}; @@ -30,7 +30,7 @@ impl traits::Service for FSEvents { &mut self, _info: &super::types::ChannelInfo, message: goval::Command, - _session: i32, + _session: Session, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/gcsfiles.rs b/services/src/gcsfiles.rs index 0249271..19d0bcc 100644 --- a/services/src/gcsfiles.rs +++ b/services/src/gcsfiles.rs @@ -1,5 +1,7 @@ pub struct GCSFiles {} +use crate::Session; + use super::traits; use anyhow::{format_err, Result}; use async_trait::async_trait; @@ -12,7 +14,7 @@ impl traits::Service for GCSFiles { &mut self, _info: &super::types::ChannelInfo, message: goval::Command, - _session: i32, + _session: Session, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/git.rs b/services/src/git.rs index 0d8e273..4eae8d6 100644 --- a/services/src/git.rs +++ b/services/src/git.rs @@ -3,7 +3,7 @@ pub struct Git { } use std::collections::HashMap; -use crate::ReplspaceMessage; +use crate::{ReplspaceMessage, Session}; use super::traits; use anyhow::{format_err, Result}; @@ -17,7 +17,7 @@ impl traits::Service for Git { &mut self, _info: &super::types::ChannelInfo, message: goval::Command, - _session: i32, + _session: Session, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), @@ -61,10 +61,10 @@ impl traits::Service for Git { &mut self, info: &super::types::ChannelInfo, msg: ReplspaceMessage, - session: i32, + session: Session, respond: Option>, ) -> Result<()> { - if session == 0 { + if session == Session::zero() { warn!( ?msg, "Got replspace message from an unknown session, ignoring" diff --git a/services/src/lib.rs b/services/src/lib.rs index 6ecf37a..9da3ea9 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -115,7 +115,7 @@ impl Channel { // Private functions impl Channel { - async fn message(&mut self, message: goval::Command, session: i32) -> Result<()> { + async fn message(&mut self, message: goval::Command, session: Session) -> Result<()> { if let Some(mut msg) = self ._inner .message(&self.info, message.clone(), session) @@ -130,7 +130,7 @@ impl Channel { async fn attach( &mut self, - session: i32, + session: Session, client: ClientInfo, sender: tokio::sync::mpsc::UnboundedSender, ) -> Result<()> { @@ -149,7 +149,7 @@ impl Channel { Ok(()) } - async fn detach(&mut self, session: i32) -> Result<()> { + async fn detach(&mut self, session: Session) -> Result<()> { self.info.sessions.retain(|sess, _| sess != &session); self.info.clients.retain(|sess, _| sess != &session); self._inner.detach(&self.info, session).await?; diff --git a/services/src/ot.rs b/services/src/ot.rs index 361fead..9fa34e8 100644 --- a/services/src/ot.rs +++ b/services/src/ot.rs @@ -13,7 +13,7 @@ use std::{ time::{Duration, SystemTime, UNIX_EPOCH}, }; -use crate::{client::ClientInfo, fs_watcher::FSWatcher, FSEvent, IPCMessage}; +use crate::{client::ClientInfo, fs_watcher::FSWatcher, FSEvent, IPCMessage, Session}; use super::traits; use anyhow::{format_err, Result}; @@ -48,7 +48,7 @@ impl traits::Service for OT { &mut self, info: &super::types::ChannelInfo, message: goval::Command, - session: i32, + session: Session, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), @@ -384,7 +384,7 @@ impl traits::Service for OT { &mut self, _info: &super::types::ChannelInfo, _client: ClientInfo, - _session: i32, + _session: Session, _sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { if self.path.is_empty() { diff --git a/services/src/output.rs b/services/src/output.rs index 9054426..123c9d1 100644 --- a/services/src/output.rs +++ b/services/src/output.rs @@ -16,7 +16,7 @@ use tracing::{debug, warn}; use super::traits; use super::types::pty::Pty; -use crate::{ClientInfo, IPCMessage}; +use crate::{ClientInfo, IPCMessage, Session}; use anyhow::{format_err, Result}; #[async_trait] @@ -25,7 +25,7 @@ impl traits::Service for Output { &mut self, info: &super::types::ChannelInfo, _client: ClientInfo, - session: i32, + session: Session, sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { if let Some(pty) = &mut self.pty { @@ -58,7 +58,7 @@ impl traits::Service for Output { Ok(Some(status)) } - async fn detach(&mut self, _info: &super::types::ChannelInfo, session: i32) -> Result<()> { + async fn detach(&mut self, _info: &super::types::ChannelInfo, session: Session) -> Result<()> { if let Some(pty) = &mut self.pty { pty.session_leave(session).await?; } @@ -69,7 +69,7 @@ impl traits::Service for Output { &mut self, info: &super::types::ChannelInfo, message: goval::Command, - _session: i32, + _session: Session, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/presence.rs b/services/src/presence.rs index 3cdd0ad..fcb2ff7 100644 --- a/services/src/presence.rs +++ b/services/src/presence.rs @@ -1,8 +1,8 @@ pub struct Presence { users: Vec, - files: HashMap, + files: HashMap, } -use crate::{ClientInfo, IPCMessage, SendSessions}; +use crate::{ClientInfo, IPCMessage, SendSessions, Session}; use std::{ collections::HashMap, time::{SystemTime, UNIX_EPOCH}, @@ -28,7 +28,7 @@ impl traits::Service for Presence { &mut self, info: &super::types::ChannelInfo, message: goval::Command, - session: i32, + session: Session, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), @@ -39,25 +39,28 @@ impl traits::Service for Presence { goval::command::Body::FollowUser(follow) => { let follow_notif = goval::Command { body: Some(goval::command::Body::FollowUser(goval::FollowUser { - session, + session: session.into(), })), ..Default::default() }; - info.send(follow_notif, SendSessions::Only(follow.session)) + info.send(follow_notif, SendSessions::Only(Session(follow.session))) .await?; Ok(None) } goval::command::Body::UnfollowUser(unfollow) => { let unfollow_notif = goval::Command { body: Some(goval::command::Body::UnfollowUser(goval::UnfollowUser { - session, + session: session.into(), })), ..Default::default() }; - info.send(unfollow_notif, SendSessions::Only(unfollow.session)) - .await?; + info.send( + unfollow_notif, + SendSessions::Only(Session(unfollow.session)), + ) + .await?; Ok(None) } goval::command::Body::OpenFile(file) => { @@ -76,7 +79,7 @@ impl traits::Service for Presence { let _inner = goval::FileOpened { user_id: user.id, file: file.file, - session, + session: session.into(), timestamp, }; @@ -98,7 +101,7 @@ impl traits::Service for Presence { &mut self, info: &super::types::ChannelInfo, client: ClientInfo, - session: i32, + session: Session, _sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { let mut roster = goval::Command::default(); @@ -115,7 +118,7 @@ impl traits::Service for Presence { roster.body = Some(goval::command::Body::Roster(_inner)); let user = goval::User { - session, + session: session.into(), id: client.id, name: client.username, ..Default::default() @@ -134,14 +137,14 @@ impl traits::Service for Presence { Ok(Some(roster)) } - async fn detach(&mut self, info: &super::types::ChannelInfo, session: i32) -> Result<()> { + async fn detach(&mut self, info: &super::types::ChannelInfo, session: Session) -> Result<()> { self.files.remove(&session); let mut part = goval::Command::default(); let mut flag = false; let users = self.users.clone(); for (idx, user) in users.iter().enumerate() { - if user.session == session { + if user.session == session.0 { flag = true; part.body = Some(goval::command::Body::Part(user.clone())); self.users.swap_remove(idx); diff --git a/services/src/shell.rs b/services/src/shell.rs index d74f041..69523d0 100644 --- a/services/src/shell.rs +++ b/services/src/shell.rs @@ -9,7 +9,7 @@ use tracing::debug; use super::traits; use super::types::pty::Pty; -use crate::{ClientInfo, IPCMessage}; +use crate::{ClientInfo, IPCMessage, Session}; use anyhow::{format_err, Result}; #[async_trait] @@ -18,14 +18,14 @@ impl traits::Service for Shell { &mut self, _info: &super::types::ChannelInfo, _client: ClientInfo, - session: i32, + session: Session, sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { self.pty.session_join(session, sender).await?; Ok(None) } - async fn detach(&mut self, _info: &super::types::ChannelInfo, session: i32) -> Result<()> { + async fn detach(&mut self, _info: &super::types::ChannelInfo, session: Session) -> Result<()> { self.pty.session_leave(session).await?; Ok(()) } @@ -34,7 +34,7 @@ impl traits::Service for Shell { &mut self, _info: &super::types::ChannelInfo, message: goval::Command, - _session: i32, + _session: Session, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/snapshot.rs b/services/src/snapshot.rs index 7def841..21e568d 100644 --- a/services/src/snapshot.rs +++ b/services/src/snapshot.rs @@ -1,5 +1,7 @@ pub struct Snapshot {} +use crate::Session; + use super::traits; use anyhow::{format_err, Result}; use async_trait::async_trait; @@ -10,7 +12,7 @@ impl traits::Service for Snapshot { &mut self, _info: &super::types::ChannelInfo, message: goval::Command, - _session: i32, + _session: Session, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/toolchain.rs b/services/src/toolchain.rs index 9610df5..48b7217 100644 --- a/services/src/toolchain.rs +++ b/services/src/toolchain.rs @@ -1,4 +1,6 @@ pub struct Toolchain {} +use crate::Session; + use super::traits; use async_trait::async_trait; use tracing::debug; @@ -11,7 +13,7 @@ impl traits::Service for Toolchain { &mut self, _info: &super::types::ChannelInfo, // TODO: use this to give real toolchain info message: goval::Command, - _session: i32, + _session: Session, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/traits.rs b/services/src/traits.rs index a3ae67c..e0e19b8 100644 --- a/services/src/traits.rs +++ b/services/src/traits.rs @@ -2,7 +2,7 @@ use anyhow::Result; use async_trait::async_trait; use tokio::sync::mpsc::Sender; -use crate::{ClientInfo, FSEvent, IPCMessage, ReplspaceMessage}; +use crate::{ClientInfo, FSEvent, IPCMessage, ReplspaceMessage, Session}; #[async_trait] pub(crate) trait Service { @@ -18,7 +18,7 @@ pub(crate) trait Service { &mut self, _info: &super::types::ChannelInfo, _message: goval::Command, - _session: i32, + _session: Session, ) -> Result> { Ok(None) } @@ -35,7 +35,7 @@ pub(crate) trait Service { &mut self, _info: &super::types::ChannelInfo, _msg: ReplspaceMessage, - _session: i32, + _session: Session, _respond: Option>, ) -> Result<()> { Ok(()) @@ -49,13 +49,13 @@ pub(crate) trait Service { &mut self, _info: &super::types::ChannelInfo, _client: ClientInfo, - _session: i32, + _session: Session, _sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { Ok(None) } - async fn detach(&mut self, _info: &super::types::ChannelInfo, _session: i32) -> Result<()> { + async fn detach(&mut self, _info: &super::types::ChannelInfo, _session: Session) -> Result<()> { Ok(()) } } diff --git a/services/src/types/channel_info.rs b/services/src/types/channel_info.rs index 3b51ab9..3b93ad9 100644 --- a/services/src/types/channel_info.rs +++ b/services/src/types/channel_info.rs @@ -6,23 +6,24 @@ use tokio::sync::RwLock; use tracing::error; use crate::config::dotreplit::DotReplit; +use crate::Session; use super::client::ClientInfo; use super::messaging::IPCMessage; #[derive(Clone, Copy, Debug)] pub enum SendSessions { - Only(i32), - EveryoneExcept(i32), + Only(Session), + EveryoneExcept(Session), Everyone, } pub struct ChannelInfo { pub id: i32, - pub clients: HashMap>, + pub clients: HashMap>, pub service: String, pub name: Option, - pub sessions: HashMap, + pub sessions: HashMap, pub sender: tokio::sync::mpsc::UnboundedSender, pub dotreplit: Arc>, pub child_env_vars: Arc>>, @@ -30,7 +31,7 @@ pub struct ChannelInfo { impl ChannelInfo { pub async fn send(&self, mut message: goval::Command, sessions: SendSessions) -> Result<()> { - let clients: Vec; + let clients: Vec; message.channel = self.id; match sessions { SendSessions::Everyone => { @@ -43,7 +44,7 @@ impl ChannelInfo { clients = _clients; } SendSessions::EveryoneExcept(excluded) => { - message.session = -excluded; + message.session = (-excluded).into(); let mut _clients = vec![]; for client in self.clients.keys() { if client != &excluded { @@ -54,7 +55,7 @@ impl ChannelInfo { clients = _clients; } SendSessions::Only(session) => { - message.session = session; + message.session = session.into(); clients = vec![session] } } diff --git a/services/src/types/messaging.rs b/services/src/types/messaging.rs index 5c90f9f..ac542f1 100644 --- a/services/src/types/messaging.rs +++ b/services/src/types/messaging.rs @@ -3,7 +3,7 @@ use prost::Message; use serde::{Deserialize, Serialize}; use tokio::sync::mpsc::Sender; -use crate::SendSessions; +use crate::{SendSessions, Session}; use super::client::ClientInfo; @@ -22,14 +22,14 @@ pub enum ReplspaceMessage { pub enum ChannelMessage { IPC(IPCMessage), Attach( - i32, + Session, ClientInfo, tokio::sync::mpsc::UnboundedSender, ), - Detach(i32), + Detach(Session), ProcessDead(i32), FSEvent(super::FSEvent), - Replspace(i32, ReplspaceMessage, Option>), // session, message + Replspace(Session, ReplspaceMessage, Option>), // session, message Shutdown, ExternalMessage(goval::Command, SendSessions), } @@ -37,7 +37,7 @@ pub enum ChannelMessage { #[derive(Debug, Clone)] pub struct IPCMessage { pub command: goval::Command, - pub session: i32, + pub session: Session, } impl IPCMessage { @@ -59,7 +59,7 @@ impl TryFrom> for IPCMessage { fn try_from(value: Vec) -> Result { Ok(Self { command: goval::Command::decode(value.as_slice())?, - session: 0, + session: Session::zero(), }) } } diff --git a/services/src/types/mod.rs b/services/src/types/mod.rs index b3ecc3d..c7fb2df 100644 --- a/services/src/types/mod.rs +++ b/services/src/types/mod.rs @@ -21,3 +21,6 @@ pub use config::dotreplit::DotReplit; pub mod proc; pub use proc::Proc; + +pub mod session; +pub use session::Session; diff --git a/services/src/types/pty.rs b/services/src/types/pty.rs index 7749ea0..443ab04 100644 --- a/services/src/types/pty.rs +++ b/services/src/types/pty.rs @@ -8,7 +8,7 @@ use std::{ }; use tracing::error; -use crate::ChannelMessage; +use crate::{ChannelMessage, Session}; use super::IPCMessage; @@ -23,7 +23,7 @@ use tokio::sync::{Mutex, RwLock}; struct PtyWriter { channel: i32, - sessions: Arc>>>, + sessions: Arc>>>, cancelled: Arc, scrollback: Arc>, } @@ -67,7 +67,7 @@ impl Write for PtyWriter { for (session, sender) in sessions.iter() { let mut to_send = cmd.clone(); - to_send.session = *session; + to_send.session = (*session).into(); match sender.send(IPCMessage { command: to_send, @@ -90,7 +90,7 @@ impl Write for PtyWriter { pub struct Pty { channel: i32, - pub sessions: Arc>>>, + pub sessions: Arc>>>, writer: Box, cancelled: Arc, child_lock: Arc>>, @@ -102,7 +102,7 @@ impl Pty { pub async fn start( _args: Vec, channel: i32, - sessions: Arc>>>, + sessions: Arc>>>, contact: tokio::sync::mpsc::UnboundedSender, _env: Option>, ) -> Result { @@ -269,7 +269,7 @@ impl Pty { pub async fn session_join( &mut self, - session: i32, + session: Session, sender: tokio::sync::mpsc::UnboundedSender, ) -> Result<()> { if self.cancelled.load(std::sync::atomic::Ordering::SeqCst) { @@ -280,7 +280,7 @@ impl Pty { body: Some(goval::command::Body::Output( self.scrollback.read().await.clone(), )), - session, + session: session.into(), channel: self.channel, ..Default::default() }; @@ -295,7 +295,7 @@ impl Pty { Ok(()) } - pub async fn session_leave(&mut self, session: i32) -> Result<()> { + pub async fn session_leave(&mut self, session: Session) -> Result<()> { if self.cancelled.load(std::sync::atomic::Ordering::SeqCst) { return Err(format_err!("Can't remove a session from a cancelled pty")); } diff --git a/services/src/types/session.rs b/services/src/types/session.rs new file mode 100644 index 0000000..2255fd1 --- /dev/null +++ b/services/src/types/session.rs @@ -0,0 +1,33 @@ +use std::{fmt::Display, ops::Neg}; + +#[repr(transparent)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub struct Session(pub i32); + +static SESSION_ZERO: Session = Session(0); + +impl Session { + pub fn zero() -> Session { + SESSION_ZERO + } +} + +impl Display for Session { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!("Session {{ id: {} }}", self.0)) + } +} + +impl Neg for Session { + type Output = Self; + + fn neg(self) -> Self::Output { + Self(-self.0) + } +} + +impl From for i32 { + fn from(session: Session) -> Self { + session.0 + } +} diff --git a/src/goval_server.rs b/src/goval_server.rs index fc5b5c6..4b856f2 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -13,7 +13,7 @@ use chrono::Datelike; use anyhow::Result; use goval::{Command, OpenChannel}; -use homeval_services::{ClientInfo, ServiceMetadata}; +use homeval_services::{ClientInfo, ServiceMetadata, Session}; use prost::Message; use std::{collections::HashMap, net::SocketAddr, sync::LazyLock}; use tokio::sync::{mpsc::UnboundedSender, Mutex, RwLock}; @@ -29,16 +29,16 @@ use crate::{ static MAX_SESSION: LazyLock> = LazyLock::new(|| Mutex::new(0)); -static SESSION_CHANNELS: LazyLock>>> = +static SESSION_CHANNELS: LazyLock>>> = LazyLock::new(|| RwLock::new(HashMap::new())); -static SESSION_CLIENT_INFO: LazyLock>> = +static SESSION_CLIENT_INFO: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); static CHANNEL_METADATA: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); -static CHANNEL_SESSIONS: LazyLock>>> = +static CHANNEL_SESSIONS: LazyLock>>> = LazyLock::new(|| RwLock::new(HashMap::new())); -static SESSION_MAP: LazyLock>>> = +static SESSION_MAP: LazyLock>>> = LazyLock::new(|| RwLock::new(HashMap::new())); #[derive(Clone)] @@ -90,7 +90,7 @@ async fn on_wsv2_upgrade(socket: WebSocket, token: String, state: AppState, addr debug!("Mutex acquired..."); *max_session += 1; - let session_id = *max_session; + let session_id = Session(*max_session); drop(max_session); let (send_to_session, session_recv) = mpsc::unbounded_channel::(); @@ -129,7 +129,7 @@ async fn wsv2( async fn handle_message( message: IPCMessage, session_map: &LazyLock< - tokio::sync::RwLock>>, + tokio::sync::RwLock>>, >, max_channel: &Mutex, ) { @@ -176,7 +176,7 @@ async fn handle_message( match detach_channel(close_chan.id, message.session, true).await { Ok(_) => {} Err(err) => { - error!(%err, session = message.session, channel = close_chan.id, + error!(%err, session = %message.session, channel = close_chan.id, "Error occured while detaching from channel") } } @@ -208,7 +208,7 @@ async fn open_channel( message: IPCMessage, max_channel: &Mutex, session_map: &LazyLock< - tokio::sync::RwLock>>, + tokio::sync::RwLock>>, >, ) -> Result<()> { let searcher: &str = &open_chan.service; @@ -376,8 +376,8 @@ async fn open_channel( Ok(()) } -async fn detach_channel(channel: i32, session: i32, forced: bool) -> Result<()> { - trace!(session, channel, forced, "Client is closing a channel"); +async fn detach_channel(channel: i32, session: Session, forced: bool) -> Result<()> { + trace!(%session, channel, forced, "Client is closing a channel"); SESSION_CHANNELS .write() @@ -437,7 +437,7 @@ async fn accept_connection( ws_stream: WebSocket, propagate: mpsc::UnboundedSender, mut sent: mpsc::UnboundedReceiver, - session: i32, + session: Session, client: ClientInfo, addr: SocketAddr, ) -> Result<()> { @@ -495,55 +495,48 @@ async fn accept_connection( tokio::spawn(async move { while let Some(_msg) = read.next().await { match _msg { - Ok(msg) => { - match msg { - WsMessage::Binary(buf) => { - let _message: anyhow::Result = buf.try_into(); - let message = match _message { - Ok(mut msg) => { - msg.session = session; - msg - } - Err(err) => { - error!(%err, session, "Error decoding message from client"); - continue; - } - }; - - if let Err(err) = propagate.send(message) { - error!(session = session, ?err, "An error occured when enqueing message to global message queue") + Ok(msg) => match msg { + WsMessage::Binary(buf) => { + let _message: anyhow::Result = buf.try_into(); + let message = match _message { + Ok(mut msg) => { + msg.session = session; + msg } - } - WsMessage::Close(_) => { - warn!(session, "CLOSING SESSION"); - for _channel in - SESSION_CHANNELS.read().await.get(&session).unwrap().iter() - { - let channel = *_channel; - tokio::spawn(async move { - match detach_channel(channel, session, true).await { - Ok(_) => {} - Err(err) => { - error!(%err, session, channel, "Error occured while detaching from channel") - } - } - }); + Err(err) => { + error!(%err, %session, "Error decoding message from client"); + continue; } + }; - SESSION_MAP.write().await.remove(&session); - SESSION_CLIENT_INFO.write().await.remove(&session); - SESSION_CHANNELS.write().await.remove(&session); - warn!(session, "CLOSED SESSION"); + if let Err(err) = propagate.send(message) { + error!(%session, ?err, "An error occured when enqueing message to global message queue") } - _ => {} } - } + WsMessage::Close(_) => { + warn!(%session, "CLOSING SESSION"); + for _channel in SESSION_CHANNELS.read().await.get(&session).unwrap().iter() + { + let channel = *_channel; + tokio::spawn(async move { + match detach_channel(channel, session, true).await { + Ok(_) => {} + Err(err) => { + error!(%err, %session, channel, "Error occured while detaching from channel") + } + } + }); + } + + SESSION_MAP.write().await.remove(&session); + SESSION_CLIENT_INFO.write().await.remove(&session); + SESSION_CHANNELS.write().await.remove(&session); + warn!(%session, "CLOSED SESSION"); + } + _ => {} + }, Err(err) => { - error!( - session = session, - ?err, - "An error occured while reading messages" - ); + error!(%session, ?err, "An error occured while reading messages"); } }; } @@ -554,7 +547,7 @@ async fn accept_connection( Ok(_) => {} Err(err) => { error!( - session = i.session, + session = %i.session, ?err, "An error occured while sending a message" ) diff --git a/src/main.rs b/src/main.rs index 4fc4311..dc6aff9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use std::sync::LazyLock; use std::time::Instant; use std::{collections::HashMap, io::Error, sync::Arc}; +use homeval_services::Session; use tokio::sync::RwLock; use tracing::{debug, info}; @@ -37,7 +38,7 @@ static CHANNEL_MESSAGES: LazyLock< RwLock>>, > = LazyLock::new(|| RwLock::new(HashMap::new())); // Hashmap for channel id -> last session that sent it a message -static LAST_SESSION_USING_CHANNEL: LazyLock>> = +static LAST_SESSION_USING_CHANNEL: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); // static REPLSPACE_CALLBACKS: LazyLock< diff --git a/src/replspace_server.rs b/src/replspace_server.rs index 1cb6188..72d248f 100644 --- a/src/replspace_server.rs +++ b/src/replspace_server.rs @@ -7,6 +7,7 @@ use axum::{ routing::{get, post}, Json, Router, }; +use homeval_services::Session; use serde::{Deserialize, Serialize}; use textnonce::TextNonce; use tokio::sync::mpsc::channel; @@ -53,10 +54,10 @@ async fn get_gh_token(_query: Option>) -> (StatusCode, Jso debug!(channel = query.channel, "Got git askpass"); let last_session = crate::LAST_SESSION_USING_CHANNEL.read().await; - session = *last_session.get(&query.channel).unwrap_or(&0); + session = *last_session.get(&query.channel).unwrap_or(&Session::zero()); } else { debug!("Got git askpass without channel id"); - session = 0; + session = Session::zero(); } let nonce = TextNonce::new().into_string(); @@ -137,14 +138,14 @@ async fn open_file(Json(query): Json) -> (StatusCode, Json Date: Sat, 13 Apr 2024 17:02:19 -0700 Subject: [PATCH 080/103] refactor: Rename Session to SessionID --- services/src/chat.rs | 6 ++--- services/src/dotreplit.rs | 4 ++-- services/src/exec.rs | 4 ++-- services/src/fsevents.rs | 4 ++-- services/src/gcsfiles.rs | 4 ++-- services/src/git.rs | 8 +++---- services/src/lib.rs | 6 ++--- services/src/ot.rs | 6 ++--- services/src/output.rs | 12 ++++++---- services/src/presence.rs | 14 +++++------ services/src/shell.rs | 12 ++++++---- services/src/snapshot.rs | 4 ++-- services/src/toolchain.rs | 4 ++-- services/src/traits.rs | 14 +++++++---- services/src/types/channel_info.rs | 12 +++++----- services/src/types/messaging.rs | 16 ++++++++----- services/src/types/mod.rs | 4 ++-- services/src/types/pty.rs | 12 +++++----- .../src/types/{session.rs => session_id.rs} | 18 +++++++------- src/goval_server.rs | 24 +++++++++++-------- src/main.rs | 4 ++-- src/replspace_server.rs | 14 ++++++----- 22 files changed, 114 insertions(+), 92 deletions(-) rename services/src/types/{session.rs => session_id.rs} (52%) diff --git a/services/src/chat.rs b/services/src/chat.rs index 019059b..30f12e9 100644 --- a/services/src/chat.rs +++ b/services/src/chat.rs @@ -2,7 +2,7 @@ pub struct Chat { history: Vec, } -use crate::{ClientInfo, IPCMessage, SendSessions, Session}; +use crate::{ClientInfo, IPCMessage, SendSessions, SessionID}; use super::traits; use anyhow::{format_err, Result}; @@ -21,7 +21,7 @@ impl traits::Service for Chat { &mut self, info: &super::types::ChannelInfo, message: goval::Command, - session: Session, + session: SessionID, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), @@ -51,7 +51,7 @@ impl traits::Service for Chat { &mut self, _info: &super::types::ChannelInfo, _client: ClientInfo, - _session: Session, + _session: SessionID, _sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { let mut scrollback = goval::Command::default(); diff --git a/services/src/dotreplit.rs b/services/src/dotreplit.rs index 0e96f98..1dfb616 100644 --- a/services/src/dotreplit.rs +++ b/services/src/dotreplit.rs @@ -1,5 +1,5 @@ pub struct DotReplit {} -use crate::Session; +use crate::SessionID; use super::traits; @@ -12,7 +12,7 @@ impl traits::Service for DotReplit { &mut self, _info: &super::types::ChannelInfo, message: goval::Command, - _session: Session, + _session: SessionID, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/exec.rs b/services/src/exec.rs index 6e32253..ff0a463 100644 --- a/services/src/exec.rs +++ b/services/src/exec.rs @@ -4,7 +4,7 @@ pub struct Exec { current_ref: String, } -use crate::{Proc, Session}; +use crate::{Proc, SessionID}; use super::traits; use anyhow::{format_err, Result}; @@ -16,7 +16,7 @@ impl traits::Service for Exec { &mut self, info: &super::types::ChannelInfo, message: goval::Command, - _session: Session, + _session: SessionID, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/fsevents.rs b/services/src/fsevents.rs index 86fc295..00738ac 100644 --- a/services/src/fsevents.rs +++ b/services/src/fsevents.rs @@ -4,7 +4,7 @@ pub struct FSEvents { } use super::traits; -use crate::{FSEvent, FSWatcher, Session}; +use crate::{FSEvent, FSWatcher, SessionID}; use anyhow::{format_err, Result}; use goval::{Command, File, FileEvent}; use tracing::{error, trace, warn}; @@ -30,7 +30,7 @@ impl traits::Service for FSEvents { &mut self, _info: &super::types::ChannelInfo, message: goval::Command, - _session: Session, + _session: SessionID, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/gcsfiles.rs b/services/src/gcsfiles.rs index 19d0bcc..bbaddfc 100644 --- a/services/src/gcsfiles.rs +++ b/services/src/gcsfiles.rs @@ -1,6 +1,6 @@ pub struct GCSFiles {} -use crate::Session; +use crate::SessionID; use super::traits; use anyhow::{format_err, Result}; @@ -14,7 +14,7 @@ impl traits::Service for GCSFiles { &mut self, _info: &super::types::ChannelInfo, message: goval::Command, - _session: Session, + _session: SessionID, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/git.rs b/services/src/git.rs index 4eae8d6..6147f3e 100644 --- a/services/src/git.rs +++ b/services/src/git.rs @@ -3,7 +3,7 @@ pub struct Git { } use std::collections::HashMap; -use crate::{ReplspaceMessage, Session}; +use crate::{ReplspaceMessage, SessionID}; use super::traits; use anyhow::{format_err, Result}; @@ -17,7 +17,7 @@ impl traits::Service for Git { &mut self, _info: &super::types::ChannelInfo, message: goval::Command, - _session: Session, + _session: SessionID, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), @@ -61,10 +61,10 @@ impl traits::Service for Git { &mut self, info: &super::types::ChannelInfo, msg: ReplspaceMessage, - session: Session, + session: SessionID, respond: Option>, ) -> Result<()> { - if session == Session::zero() { + if session == SessionID::zero() { warn!( ?msg, "Got replspace message from an unknown session, ignoring" diff --git a/services/src/lib.rs b/services/src/lib.rs index 9da3ea9..cd97685 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -115,7 +115,7 @@ impl Channel { // Private functions impl Channel { - async fn message(&mut self, message: goval::Command, session: Session) -> Result<()> { + async fn message(&mut self, message: goval::Command, session: SessionID) -> Result<()> { if let Some(mut msg) = self ._inner .message(&self.info, message.clone(), session) @@ -130,7 +130,7 @@ impl Channel { async fn attach( &mut self, - session: Session, + session: SessionID, client: ClientInfo, sender: tokio::sync::mpsc::UnboundedSender, ) -> Result<()> { @@ -149,7 +149,7 @@ impl Channel { Ok(()) } - async fn detach(&mut self, session: Session) -> Result<()> { + async fn detach(&mut self, session: SessionID) -> Result<()> { self.info.sessions.retain(|sess, _| sess != &session); self.info.clients.retain(|sess, _| sess != &session); self._inner.detach(&self.info, session).await?; diff --git a/services/src/ot.rs b/services/src/ot.rs index 9fa34e8..060bf8e 100644 --- a/services/src/ot.rs +++ b/services/src/ot.rs @@ -13,7 +13,7 @@ use std::{ time::{Duration, SystemTime, UNIX_EPOCH}, }; -use crate::{client::ClientInfo, fs_watcher::FSWatcher, FSEvent, IPCMessage, Session}; +use crate::{client::ClientInfo, fs_watcher::FSWatcher, FSEvent, IPCMessage, SessionID}; use super::traits; use anyhow::{format_err, Result}; @@ -48,7 +48,7 @@ impl traits::Service for OT { &mut self, info: &super::types::ChannelInfo, message: goval::Command, - session: Session, + session: SessionID, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), @@ -384,7 +384,7 @@ impl traits::Service for OT { &mut self, _info: &super::types::ChannelInfo, _client: ClientInfo, - _session: Session, + _session: SessionID, _sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { if self.path.is_empty() { diff --git a/services/src/output.rs b/services/src/output.rs index 123c9d1..acb15bf 100644 --- a/services/src/output.rs +++ b/services/src/output.rs @@ -16,7 +16,7 @@ use tracing::{debug, warn}; use super::traits; use super::types::pty::Pty; -use crate::{ClientInfo, IPCMessage, Session}; +use crate::{ClientInfo, IPCMessage, SessionID}; use anyhow::{format_err, Result}; #[async_trait] @@ -25,7 +25,7 @@ impl traits::Service for Output { &mut self, info: &super::types::ChannelInfo, _client: ClientInfo, - session: Session, + session: SessionID, sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { if let Some(pty) = &mut self.pty { @@ -58,7 +58,11 @@ impl traits::Service for Output { Ok(Some(status)) } - async fn detach(&mut self, _info: &super::types::ChannelInfo, session: Session) -> Result<()> { + async fn detach( + &mut self, + _info: &super::types::ChannelInfo, + session: SessionID, + ) -> Result<()> { if let Some(pty) = &mut self.pty { pty.session_leave(session).await?; } @@ -69,7 +73,7 @@ impl traits::Service for Output { &mut self, info: &super::types::ChannelInfo, message: goval::Command, - _session: Session, + _session: SessionID, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/presence.rs b/services/src/presence.rs index fcb2ff7..0e8338c 100644 --- a/services/src/presence.rs +++ b/services/src/presence.rs @@ -1,8 +1,8 @@ pub struct Presence { users: Vec, - files: HashMap, + files: HashMap, } -use crate::{ClientInfo, IPCMessage, SendSessions, Session}; +use crate::{ClientInfo, IPCMessage, SendSessions, SessionID}; use std::{ collections::HashMap, time::{SystemTime, UNIX_EPOCH}, @@ -28,7 +28,7 @@ impl traits::Service for Presence { &mut self, info: &super::types::ChannelInfo, message: goval::Command, - session: Session, + session: SessionID, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), @@ -44,7 +44,7 @@ impl traits::Service for Presence { ..Default::default() }; - info.send(follow_notif, SendSessions::Only(Session(follow.session))) + info.send(follow_notif, SendSessions::Only(SessionID(follow.session))) .await?; Ok(None) } @@ -58,7 +58,7 @@ impl traits::Service for Presence { info.send( unfollow_notif, - SendSessions::Only(Session(unfollow.session)), + SendSessions::Only(SessionID(unfollow.session)), ) .await?; Ok(None) @@ -101,7 +101,7 @@ impl traits::Service for Presence { &mut self, info: &super::types::ChannelInfo, client: ClientInfo, - session: Session, + session: SessionID, _sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { let mut roster = goval::Command::default(); @@ -137,7 +137,7 @@ impl traits::Service for Presence { Ok(Some(roster)) } - async fn detach(&mut self, info: &super::types::ChannelInfo, session: Session) -> Result<()> { + async fn detach(&mut self, info: &super::types::ChannelInfo, session: SessionID) -> Result<()> { self.files.remove(&session); let mut part = goval::Command::default(); let mut flag = false; diff --git a/services/src/shell.rs b/services/src/shell.rs index 69523d0..e3bbef5 100644 --- a/services/src/shell.rs +++ b/services/src/shell.rs @@ -9,7 +9,7 @@ use tracing::debug; use super::traits; use super::types::pty::Pty; -use crate::{ClientInfo, IPCMessage, Session}; +use crate::{ClientInfo, IPCMessage, SessionID}; use anyhow::{format_err, Result}; #[async_trait] @@ -18,14 +18,18 @@ impl traits::Service for Shell { &mut self, _info: &super::types::ChannelInfo, _client: ClientInfo, - session: Session, + session: SessionID, sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { self.pty.session_join(session, sender).await?; Ok(None) } - async fn detach(&mut self, _info: &super::types::ChannelInfo, session: Session) -> Result<()> { + async fn detach( + &mut self, + _info: &super::types::ChannelInfo, + session: SessionID, + ) -> Result<()> { self.pty.session_leave(session).await?; Ok(()) } @@ -34,7 +38,7 @@ impl traits::Service for Shell { &mut self, _info: &super::types::ChannelInfo, message: goval::Command, - _session: Session, + _session: SessionID, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/snapshot.rs b/services/src/snapshot.rs index 21e568d..a0a7779 100644 --- a/services/src/snapshot.rs +++ b/services/src/snapshot.rs @@ -1,6 +1,6 @@ pub struct Snapshot {} -use crate::Session; +use crate::SessionID; use super::traits; use anyhow::{format_err, Result}; @@ -12,7 +12,7 @@ impl traits::Service for Snapshot { &mut self, _info: &super::types::ChannelInfo, message: goval::Command, - _session: Session, + _session: SessionID, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/toolchain.rs b/services/src/toolchain.rs index 48b7217..64d3bf2 100644 --- a/services/src/toolchain.rs +++ b/services/src/toolchain.rs @@ -1,5 +1,5 @@ pub struct Toolchain {} -use crate::Session; +use crate::SessionID; use super::traits; use async_trait::async_trait; @@ -13,7 +13,7 @@ impl traits::Service for Toolchain { &mut self, _info: &super::types::ChannelInfo, // TODO: use this to give real toolchain info message: goval::Command, - _session: Session, + _session: SessionID, ) -> Result> { let body = match message.body.clone() { None => return Err(format_err!("Expected command body")), diff --git a/services/src/traits.rs b/services/src/traits.rs index e0e19b8..e393303 100644 --- a/services/src/traits.rs +++ b/services/src/traits.rs @@ -2,7 +2,7 @@ use anyhow::Result; use async_trait::async_trait; use tokio::sync::mpsc::Sender; -use crate::{ClientInfo, FSEvent, IPCMessage, ReplspaceMessage, Session}; +use crate::{ClientInfo, FSEvent, IPCMessage, ReplspaceMessage, SessionID}; #[async_trait] pub(crate) trait Service { @@ -18,7 +18,7 @@ pub(crate) trait Service { &mut self, _info: &super::types::ChannelInfo, _message: goval::Command, - _session: Session, + _session: SessionID, ) -> Result> { Ok(None) } @@ -35,7 +35,7 @@ pub(crate) trait Service { &mut self, _info: &super::types::ChannelInfo, _msg: ReplspaceMessage, - _session: Session, + _session: SessionID, _respond: Option>, ) -> Result<()> { Ok(()) @@ -49,13 +49,17 @@ pub(crate) trait Service { &mut self, _info: &super::types::ChannelInfo, _client: ClientInfo, - _session: Session, + _session: SessionID, _sender: tokio::sync::mpsc::UnboundedSender, ) -> Result> { Ok(None) } - async fn detach(&mut self, _info: &super::types::ChannelInfo, _session: Session) -> Result<()> { + async fn detach( + &mut self, + _info: &super::types::ChannelInfo, + _session: SessionID, + ) -> Result<()> { Ok(()) } } diff --git a/services/src/types/channel_info.rs b/services/src/types/channel_info.rs index 3b93ad9..7661f5f 100644 --- a/services/src/types/channel_info.rs +++ b/services/src/types/channel_info.rs @@ -6,24 +6,24 @@ use tokio::sync::RwLock; use tracing::error; use crate::config::dotreplit::DotReplit; -use crate::Session; +use crate::SessionID; use super::client::ClientInfo; use super::messaging::IPCMessage; #[derive(Clone, Copy, Debug)] pub enum SendSessions { - Only(Session), - EveryoneExcept(Session), + Only(SessionID), + EveryoneExcept(SessionID), Everyone, } pub struct ChannelInfo { pub id: i32, - pub clients: HashMap>, + pub clients: HashMap>, pub service: String, pub name: Option, - pub sessions: HashMap, + pub sessions: HashMap, pub sender: tokio::sync::mpsc::UnboundedSender, pub dotreplit: Arc>, pub child_env_vars: Arc>>, @@ -31,7 +31,7 @@ pub struct ChannelInfo { impl ChannelInfo { pub async fn send(&self, mut message: goval::Command, sessions: SendSessions) -> Result<()> { - let clients: Vec; + let clients: Vec; message.channel = self.id; match sessions { SendSessions::Everyone => { diff --git a/services/src/types/messaging.rs b/services/src/types/messaging.rs index ac542f1..d6bd91e 100644 --- a/services/src/types/messaging.rs +++ b/services/src/types/messaging.rs @@ -3,7 +3,7 @@ use prost::Message; use serde::{Deserialize, Serialize}; use tokio::sync::mpsc::Sender; -use crate::{SendSessions, Session}; +use crate::{SendSessions, SessionID}; use super::client::ClientInfo; @@ -22,14 +22,18 @@ pub enum ReplspaceMessage { pub enum ChannelMessage { IPC(IPCMessage), Attach( - Session, + SessionID, ClientInfo, tokio::sync::mpsc::UnboundedSender, ), - Detach(Session), + Detach(SessionID), ProcessDead(i32), FSEvent(super::FSEvent), - Replspace(Session, ReplspaceMessage, Option>), // session, message + Replspace( + SessionID, + ReplspaceMessage, + Option>, + ), // session, message Shutdown, ExternalMessage(goval::Command, SendSessions), } @@ -37,7 +41,7 @@ pub enum ChannelMessage { #[derive(Debug, Clone)] pub struct IPCMessage { pub command: goval::Command, - pub session: Session, + pub session: SessionID, } impl IPCMessage { @@ -59,7 +63,7 @@ impl TryFrom> for IPCMessage { fn try_from(value: Vec) -> Result { Ok(Self { command: goval::Command::decode(value.as_slice())?, - session: Session::zero(), + session: SessionID::zero(), }) } } diff --git a/services/src/types/mod.rs b/services/src/types/mod.rs index c7fb2df..cf0d5fc 100644 --- a/services/src/types/mod.rs +++ b/services/src/types/mod.rs @@ -22,5 +22,5 @@ pub use config::dotreplit::DotReplit; pub mod proc; pub use proc::Proc; -pub mod session; -pub use session::Session; +pub mod session_id; +pub use session_id::SessionID; diff --git a/services/src/types/pty.rs b/services/src/types/pty.rs index 443ab04..cdd0572 100644 --- a/services/src/types/pty.rs +++ b/services/src/types/pty.rs @@ -8,7 +8,7 @@ use std::{ }; use tracing::error; -use crate::{ChannelMessage, Session}; +use crate::{ChannelMessage, SessionID}; use super::IPCMessage; @@ -23,7 +23,7 @@ use tokio::sync::{Mutex, RwLock}; struct PtyWriter { channel: i32, - sessions: Arc>>>, + sessions: Arc>>>, cancelled: Arc, scrollback: Arc>, } @@ -90,7 +90,7 @@ impl Write for PtyWriter { pub struct Pty { channel: i32, - pub sessions: Arc>>>, + pub sessions: Arc>>>, writer: Box, cancelled: Arc, child_lock: Arc>>, @@ -102,7 +102,7 @@ impl Pty { pub async fn start( _args: Vec, channel: i32, - sessions: Arc>>>, + sessions: Arc>>>, contact: tokio::sync::mpsc::UnboundedSender, _env: Option>, ) -> Result { @@ -269,7 +269,7 @@ impl Pty { pub async fn session_join( &mut self, - session: Session, + session: SessionID, sender: tokio::sync::mpsc::UnboundedSender, ) -> Result<()> { if self.cancelled.load(std::sync::atomic::Ordering::SeqCst) { @@ -295,7 +295,7 @@ impl Pty { Ok(()) } - pub async fn session_leave(&mut self, session: Session) -> Result<()> { + pub async fn session_leave(&mut self, session: SessionID) -> Result<()> { if self.cancelled.load(std::sync::atomic::Ordering::SeqCst) { return Err(format_err!("Can't remove a session from a cancelled pty")); } diff --git a/services/src/types/session.rs b/services/src/types/session_id.rs similarity index 52% rename from services/src/types/session.rs rename to services/src/types/session_id.rs index 2255fd1..dbdc2c8 100644 --- a/services/src/types/session.rs +++ b/services/src/types/session_id.rs @@ -2,23 +2,23 @@ use std::{fmt::Display, ops::Neg}; #[repr(transparent)] #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] -pub struct Session(pub i32); +pub struct SessionID(pub i32); -static SESSION_ZERO: Session = Session(0); +static SESSION_ZERO: SessionID = SessionID(0); -impl Session { - pub fn zero() -> Session { +impl SessionID { + pub fn zero() -> SessionID { SESSION_ZERO } } -impl Display for Session { +impl Display for SessionID { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_fmt(format_args!("Session {{ id: {} }}", self.0)) + f.write_fmt(format_args!("SessionID {{ id: {} }}", self.0)) } } -impl Neg for Session { +impl Neg for SessionID { type Output = Self; fn neg(self) -> Self::Output { @@ -26,8 +26,8 @@ impl Neg for Session { } } -impl From for i32 { - fn from(session: Session) -> Self { +impl From for i32 { + fn from(session: SessionID) -> Self { session.0 } } diff --git a/src/goval_server.rs b/src/goval_server.rs index 4b856f2..a04a49a 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -13,7 +13,7 @@ use chrono::Datelike; use anyhow::Result; use goval::{Command, OpenChannel}; -use homeval_services::{ClientInfo, ServiceMetadata, Session}; +use homeval_services::{ClientInfo, ServiceMetadata, SessionID}; use prost::Message; use std::{collections::HashMap, net::SocketAddr, sync::LazyLock}; use tokio::sync::{mpsc::UnboundedSender, Mutex, RwLock}; @@ -29,16 +29,16 @@ use crate::{ static MAX_SESSION: LazyLock> = LazyLock::new(|| Mutex::new(0)); -static SESSION_CHANNELS: LazyLock>>> = +static SESSION_CHANNELS: LazyLock>>> = LazyLock::new(|| RwLock::new(HashMap::new())); -static SESSION_CLIENT_INFO: LazyLock>> = +static SESSION_CLIENT_INFO: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); static CHANNEL_METADATA: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); -static CHANNEL_SESSIONS: LazyLock>>> = +static CHANNEL_SESSIONS: LazyLock>>> = LazyLock::new(|| RwLock::new(HashMap::new())); -static SESSION_MAP: LazyLock>>> = +static SESSION_MAP: LazyLock>>> = LazyLock::new(|| RwLock::new(HashMap::new())); #[derive(Clone)] @@ -90,7 +90,7 @@ async fn on_wsv2_upgrade(socket: WebSocket, token: String, state: AppState, addr debug!("Mutex acquired..."); *max_session += 1; - let session_id = Session(*max_session); + let session_id = SessionID(*max_session); drop(max_session); let (send_to_session, session_recv) = mpsc::unbounded_channel::(); @@ -129,7 +129,9 @@ async fn wsv2( async fn handle_message( message: IPCMessage, session_map: &LazyLock< - tokio::sync::RwLock>>, + tokio::sync::RwLock< + std::collections::HashMap>, + >, >, max_channel: &Mutex, ) { @@ -208,7 +210,9 @@ async fn open_channel( message: IPCMessage, max_channel: &Mutex, session_map: &LazyLock< - tokio::sync::RwLock>>, + tokio::sync::RwLock< + std::collections::HashMap>, + >, >, ) -> Result<()> { let searcher: &str = &open_chan.service; @@ -376,7 +380,7 @@ async fn open_channel( Ok(()) } -async fn detach_channel(channel: i32, session: Session, forced: bool) -> Result<()> { +async fn detach_channel(channel: i32, session: SessionID, forced: bool) -> Result<()> { trace!(%session, channel, forced, "Client is closing a channel"); SESSION_CHANNELS @@ -437,7 +441,7 @@ async fn accept_connection( ws_stream: WebSocket, propagate: mpsc::UnboundedSender, mut sent: mpsc::UnboundedReceiver, - session: Session, + session: SessionID, client: ClientInfo, addr: SocketAddr, ) -> Result<()> { diff --git a/src/main.rs b/src/main.rs index dc6aff9..a059ee9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use std::sync::LazyLock; use std::time::Instant; use std::{collections::HashMap, io::Error, sync::Arc}; -use homeval_services::Session; +use homeval_services::SessionID; use tokio::sync::RwLock; use tracing::{debug, info}; @@ -38,7 +38,7 @@ static CHANNEL_MESSAGES: LazyLock< RwLock>>, > = LazyLock::new(|| RwLock::new(HashMap::new())); // Hashmap for channel id -> last session that sent it a message -static LAST_SESSION_USING_CHANNEL: LazyLock>> = +static LAST_SESSION_USING_CHANNEL: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); // static REPLSPACE_CALLBACKS: LazyLock< diff --git a/src/replspace_server.rs b/src/replspace_server.rs index 72d248f..c8089f1 100644 --- a/src/replspace_server.rs +++ b/src/replspace_server.rs @@ -7,7 +7,7 @@ use axum::{ routing::{get, post}, Json, Router, }; -use homeval_services::Session; +use homeval_services::SessionID; use serde::{Deserialize, Serialize}; use textnonce::TextNonce; use tokio::sync::mpsc::channel; @@ -54,10 +54,12 @@ async fn get_gh_token(_query: Option>) -> (StatusCode, Jso debug!(channel = query.channel, "Got git askpass"); let last_session = crate::LAST_SESSION_USING_CHANNEL.read().await; - session = *last_session.get(&query.channel).unwrap_or(&Session::zero()); + session = *last_session + .get(&query.channel) + .unwrap_or(&SessionID::zero()); } else { debug!("Got git askpass without channel id"); - session = Session::zero(); + session = SessionID::zero(); } let nonce = TextNonce::new().into_string(); @@ -138,14 +140,14 @@ async fn open_file(Json(query): Json) -> (StatusCode, Json Date: Sat, 13 Apr 2024 17:22:45 -0700 Subject: [PATCH 081/103] fix(services): Fix pty implementation --- services/src/types/pty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/src/types/pty.rs b/services/src/types/pty.rs index cdd0572..62c0b23 100644 --- a/services/src/types/pty.rs +++ b/services/src/types/pty.rs @@ -171,6 +171,7 @@ impl Pty { let child_lock_reaper = child_lock.clone(); + tokio::task::spawn(async move { let task_res = tokio::task::spawn(async move { let mut interval = tokio::time::interval(Duration::from_millis(50)); @@ -185,7 +186,6 @@ impl Pty { }) .await; - tokio::task::spawn(async move { match task_res { Ok(res) => { match res { From e42e133923611321046c24025c5c4cb2bdc78689 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 13 Apr 2024 17:29:53 -0700 Subject: [PATCH 082/103] refactor: Use special new type for channel ids instead of i32 --- services/src/lib.rs | 2 +- services/src/shell.rs | 1 + services/src/types/channel_id.rs | 17 ++++++++++++ services/src/types/channel_info.rs | 6 ++-- services/src/types/mod.rs | 3 ++ services/src/types/proc.rs | 10 +++---- services/src/types/pty.rs | 44 +++++++++++++----------------- services/src/types/service.rs | 4 ++- src/goval_server.rs | 37 +++++++++++++------------ src/main.rs | 6 ++-- src/replspace_server.rs | 8 ++++-- 11 files changed, 79 insertions(+), 59 deletions(-) create mode 100644 services/src/types/channel_id.rs diff --git a/services/src/lib.rs b/services/src/lib.rs index cd97685..71dcccb 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -30,7 +30,7 @@ pub struct Channel { // Public functions impl Channel { pub async fn new( - id: i32, + id: ChannelID, service: String, name: Option, dotreplit: Arc>, diff --git a/services/src/shell.rs b/services/src/shell.rs index e3bbef5..24c5760 100644 --- a/services/src/shell.rs +++ b/services/src/shell.rs @@ -78,6 +78,7 @@ impl Shell { async fn start_pty(info: &super::types::ChannelInfo) -> Result { let mut env = HashMap::new(); env.insert("REPLIT_GIT_TOOLS_CHANNEL_FROM".into(), info.id.to_string()); + Pty::start( vec![std::env::var("SHELL").unwrap_or(DEFAULT_SHELL.to_string())], info.id, diff --git a/services/src/types/channel_id.rs b/services/src/types/channel_id.rs new file mode 100644 index 0000000..29e46f7 --- /dev/null +++ b/services/src/types/channel_id.rs @@ -0,0 +1,17 @@ +use std::fmt::Display; + +#[repr(transparent)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)] +pub struct ChannelID(pub i32); + +impl Display for ChannelID { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!("Channel {{ id: {} }}", self.0)) + } +} + +impl From for i32 { + fn from(channel: ChannelID) -> Self { + channel.0 + } +} diff --git a/services/src/types/channel_info.rs b/services/src/types/channel_info.rs index 7661f5f..cb9bcf8 100644 --- a/services/src/types/channel_info.rs +++ b/services/src/types/channel_info.rs @@ -6,7 +6,7 @@ use tokio::sync::RwLock; use tracing::error; use crate::config::dotreplit::DotReplit; -use crate::SessionID; +use crate::{ChannelID, SessionID}; use super::client::ClientInfo; use super::messaging::IPCMessage; @@ -19,7 +19,7 @@ pub enum SendSessions { } pub struct ChannelInfo { - pub id: i32, + pub id: ChannelID, pub clients: HashMap>, pub service: String, pub name: Option, @@ -32,7 +32,7 @@ pub struct ChannelInfo { impl ChannelInfo { pub async fn send(&self, mut message: goval::Command, sessions: SendSessions) -> Result<()> { let clients: Vec; - message.channel = self.id; + message.channel = self.id.into(); match sessions { SendSessions::Everyone => { message.session = 0; diff --git a/services/src/types/mod.rs b/services/src/types/mod.rs index cf0d5fc..ebc1ce2 100644 --- a/services/src/types/mod.rs +++ b/services/src/types/mod.rs @@ -24,3 +24,6 @@ pub use proc::Proc; pub mod session_id; pub use session_id::SessionID; + +pub mod channel_id; +pub use channel_id::ChannelID; diff --git a/services/src/types/proc.rs b/services/src/types/proc.rs index 75d6080..2aaaee1 100644 --- a/services/src/types/proc.rs +++ b/services/src/types/proc.rs @@ -6,7 +6,7 @@ use std::{ task::{Context, Poll}, }; -use crate::{ChannelMessage, SendSessions}; +use crate::{ChannelID, ChannelMessage, SendSessions}; use anyhow::Result; use tokio::{ io::{AsyncWrite, AsyncWriteExt}, @@ -15,7 +15,7 @@ use tokio::{ use tracing::{error, trace}; struct CmdWriter { - channel: i32, + channel: ChannelID, contact: tokio::sync::mpsc::UnboundedSender, cancelled: Arc, error: bool, @@ -52,7 +52,7 @@ impl AsyncWrite for CmdWriter { cmd.body = Some(goval::command::Body::Output(output)); } - cmd.channel = self.channel; + cmd.channel = self.channel.into(); if self .contact .send(ChannelMessage::ExternalMessage(cmd, SendSessions::Everyone)) @@ -79,7 +79,7 @@ impl AsyncWrite for CmdWriter { } pub struct Proc { - _channel: i32, + _channel: ChannelID, cancelled: Arc, _contact: tokio::sync::mpsc::UnboundedSender, stdin: ChildStdin, @@ -88,7 +88,7 @@ pub struct Proc { impl Proc { pub async fn new( _args: Vec, - channel: i32, + channel: ChannelID, contact: tokio::sync::mpsc::UnboundedSender, _env: Option>, ) -> Result { diff --git a/services/src/types/pty.rs b/services/src/types/pty.rs index 62c0b23..4891d94 100644 --- a/services/src/types/pty.rs +++ b/services/src/types/pty.rs @@ -8,7 +8,7 @@ use std::{ }; use tracing::error; -use crate::{ChannelMessage, SessionID}; +use crate::{ChannelID, ChannelMessage, SessionID}; use super::IPCMessage; @@ -22,7 +22,7 @@ use tokio::sync::{Mutex, RwLock}; // LazyLock::new(|| RwLock::new(HashMap::new())); struct PtyWriter { - channel: i32, + channel: ChannelID, sessions: Arc>>>, cancelled: Arc, scrollback: Arc>, @@ -43,7 +43,7 @@ impl Write for PtyWriter { }; cmd.body = Some(goval::command::Body::Output(output.clone())); - cmd.channel = self.channel; + cmd.channel = self.channel.into(); if self.cancelled.load(std::sync::atomic::Ordering::SeqCst) { return Err(std::io::Error::new(ErrorKind::Other, "cancelled")); @@ -89,7 +89,7 @@ impl Write for PtyWriter { } pub struct Pty { - channel: i32, + channel: ChannelID, pub sessions: Arc>>>, writer: Box, cancelled: Arc, @@ -101,7 +101,7 @@ pub struct Pty { impl Pty { pub async fn start( _args: Vec, - channel: i32, + channel: ChannelID, sessions: Arc>>>, contact: tokio::sync::mpsc::UnboundedSender, _env: Option>, @@ -114,13 +114,7 @@ impl Pty { let pair = pty_system.openpty(PtySize { rows: 24, cols: 80, - // Not all systems support pixel_width, pixel_height, - // but it is good practice to set it to something - // that matches the size of the selected font. That - // is more complex than can be shown here in this - // brief example though! - pixel_width: 0, - pixel_height: 0, + ..Default::default() })?; let mut cmd = portable_pty::CommandBuilder::new(_args[0].clone()); @@ -172,19 +166,19 @@ impl Pty { let child_lock_reaper = child_lock.clone(); tokio::task::spawn(async move { - let task_res = tokio::task::spawn(async move { - let mut interval = tokio::time::interval(Duration::from_millis(50)); - - loop { - interval.tick().await; - let mut child_ = child_lock_reaper.lock().await; - if let Some(exit_code) = child_.try_wait()? { - return Ok::(exit_code.exit_code() as i32); + let task_res = tokio::task::spawn(async move { + let mut interval = tokio::time::interval(Duration::from_millis(50)); + + loop { + interval.tick().await; + let mut child_ = child_lock_reaper.lock().await; + if let Some(exit_code) = child_.try_wait()? { + return Ok::(exit_code.exit_code() as i32); + } + drop(child_); } - drop(child_); - } - }) - .await; + }) + .await; match task_res { Ok(res) => { @@ -281,7 +275,7 @@ impl Pty { self.scrollback.read().await.clone(), )), session: session.into(), - channel: self.channel, + channel: self.channel.into(), ..Default::default() }; diff --git a/services/src/types/service.rs b/services/src/types/service.rs index 61950ff..761e0e0 100644 --- a/services/src/types/service.rs +++ b/services/src/types/service.rs @@ -1,6 +1,8 @@ +use crate::ChannelID; + #[derive(Clone, Debug)] pub struct ServiceMetadata { pub service: String, pub name: Option, - pub id: i32, + pub id: ChannelID, } diff --git a/src/goval_server.rs b/src/goval_server.rs index a04a49a..d01516d 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -13,7 +13,7 @@ use chrono::Datelike; use anyhow::Result; use goval::{Command, OpenChannel}; -use homeval_services::{ClientInfo, ServiceMetadata, SessionID}; +use homeval_services::{ChannelID, ClientInfo, ServiceMetadata, SessionID}; use prost::Message; use std::{collections::HashMap, net::SocketAddr, sync::LazyLock}; use tokio::sync::{mpsc::UnboundedSender, Mutex, RwLock}; @@ -29,14 +29,14 @@ use crate::{ static MAX_SESSION: LazyLock> = LazyLock::new(|| Mutex::new(0)); -static SESSION_CHANNELS: LazyLock>>> = +static SESSION_CHANNELS: LazyLock>>> = LazyLock::new(|| RwLock::new(HashMap::new())); static SESSION_CLIENT_INFO: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); -static CHANNEL_METADATA: LazyLock>> = +static CHANNEL_METADATA: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); -static CHANNEL_SESSIONS: LazyLock>>> = +static CHANNEL_SESSIONS: LazyLock>>> = LazyLock::new(|| RwLock::new(HashMap::new())); static SESSION_MAP: LazyLock>>> = LazyLock::new(|| RwLock::new(HashMap::new())); @@ -175,7 +175,7 @@ async fn handle_message( goval::command::Body::CloseChan(close_chan) => { // TODO: follow close_chan.action tokio::spawn(async move { - match detach_channel(close_chan.id, message.session, true).await { + match detach_channel(ChannelID(close_chan.id), message.session, true).await { Ok(_) => {} Err(err) => { error!(%err, session = %message.session, channel = close_chan.id, @@ -188,8 +188,9 @@ async fn handle_message( } } else { let msg_lock = CHANNEL_MESSAGES.read().await; + let channel_id = ChannelID(cmd.channel); - let queue = msg_lock.get(&cmd.channel).unwrap().clone(); + let queue = msg_lock.get(&channel_id).unwrap().clone(); drop(msg_lock); @@ -199,7 +200,7 @@ async fn handle_message( let mut hashmap_lock = LAST_SESSION_USING_CHANNEL.write().await; - hashmap_lock.insert(cmd.channel, message.session); + hashmap_lock.insert(channel_id, message.session); drop(hashmap_lock); } @@ -218,7 +219,7 @@ async fn open_channel( let searcher: &str = &open_chan.service; if homeval_services::IMPLEMENTED_SERVICES.contains(&searcher) { let mut found = false; - let mut channel_id_held = 0; + let mut channel_id_held: ChannelID = ChannelID(0); let attach = open_chan.action() == goval::open_channel::Action::AttachOrCreate || open_chan.action() == goval::open_channel::Action::Attach @@ -245,7 +246,7 @@ async fn open_channel( let service = open_chan.service.clone(); let mut max_channel = max_channel.lock().await; *max_channel += 1; - let channel_id = *max_channel; + let channel_id = ChannelID(*max_channel); channel_id_held = channel_id; drop(max_channel); @@ -261,7 +262,7 @@ async fn open_channel( name: _channel_name.clone(), }; - trace!(channel = channel_id, "Awaiting queue write"); + trace!(channel = %channel_id, "Awaiting queue write"); let (writer, reader) = mpsc::unbounded_channel(); @@ -273,7 +274,7 @@ async fn open_channel( let mut metadata = CHANNEL_METADATA.write().await; metadata.insert(channel_id_held, service_data.clone()); drop(metadata); - trace!(channel = channel_id_held, "Added channel to queue list"); + trace!(channel = %channel_id_held, "Added channel to queue list"); tokio::spawn(async move { let channel = homeval_services::Channel::new( @@ -315,7 +316,7 @@ async fn open_channel( let mut open_chan_res = goval::Command::default(); let _open_res = goval::OpenChannelRes { state: goval::open_channel_res::State::Created.into(), - id: channel_id_held, + id: channel_id_held.into(), ..Default::default() }; @@ -380,14 +381,14 @@ async fn open_channel( Ok(()) } -async fn detach_channel(channel: i32, session: SessionID, forced: bool) -> Result<()> { - trace!(%session, channel, forced, "Client is closing a channel"); +async fn detach_channel(channel: ChannelID, session: SessionID, forced: bool) -> Result<()> { + trace!(%session, %channel, forced, "Client is closing a channel"); SESSION_CHANNELS .write() .await .entry(session) - .and_modify(|channels| channels.retain(|chan: &i32| *chan != channel)); + .and_modify(|channels| channels.retain(|chan| *chan != channel)); let msg_lock = CHANNEL_MESSAGES.read().await; @@ -405,7 +406,7 @@ async fn detach_channel(channel: i32, session: SessionID, forced: bool) -> Resul Some(arr) => { arr.retain(|sess| *sess != session); if arr.is_empty() { - trace!(channel, "Shutting down channel"); + trace!(%channel, "Shutting down channel"); queue.send(ChannelMessage::Shutdown)?; tokio::spawn(async move { @@ -419,7 +420,7 @@ async fn detach_channel(channel: i32, session: SessionID, forced: bool) -> Resul } } None => { - warn!(channel, "Missing CHANNEL_SESSIONS"); + warn!(%channel, "Missing CHANNEL_SESSIONS"); } } @@ -526,7 +527,7 @@ async fn accept_connection( match detach_channel(channel, session, true).await { Ok(_) => {} Err(err) => { - error!(%err, %session, channel, "Error occured while detaching from channel") + error!(%err, %session, %channel, "Error occured while detaching from channel") } } }); diff --git a/src/main.rs b/src/main.rs index a059ee9..36e8146 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use std::sync::LazyLock; use std::time::Instant; use std::{collections::HashMap, io::Error, sync::Arc}; -use homeval_services::SessionID; +use homeval_services::{ChannelID, SessionID}; use tokio::sync::RwLock; use tracing::{debug, info}; @@ -35,10 +35,10 @@ pub static DOTREPLIT_CONFIG: LazyLock>> = LazyLock::new(|| }); static CHANNEL_MESSAGES: LazyLock< - RwLock>>, + RwLock>>, > = LazyLock::new(|| RwLock::new(HashMap::new())); // Hashmap for channel id -> last session that sent it a message -static LAST_SESSION_USING_CHANNEL: LazyLock>> = +static LAST_SESSION_USING_CHANNEL: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); // static REPLSPACE_CALLBACKS: LazyLock< diff --git a/src/replspace_server.rs b/src/replspace_server.rs index c8089f1..5467774 100644 --- a/src/replspace_server.rs +++ b/src/replspace_server.rs @@ -7,7 +7,7 @@ use axum::{ routing::{get, post}, Json, Router, }; -use homeval_services::SessionID; +use homeval_services::{ChannelID, SessionID}; use serde::{Deserialize, Serialize}; use textnonce::TextNonce; use tokio::sync::mpsc::channel; @@ -55,7 +55,7 @@ async fn get_gh_token(_query: Option>) -> (StatusCode, Jso let last_session = crate::LAST_SESSION_USING_CHANNEL.read().await; session = *last_session - .get(&query.channel) + .get(&ChannelID(query.channel)) .unwrap_or(&SessionID::zero()); } else { debug!("Got git askpass without channel id"); @@ -140,7 +140,9 @@ async fn open_file(Json(query): Json) -> (StatusCode, Json Date: Sat, 13 Apr 2024 17:35:44 -0700 Subject: [PATCH 083/103] build: Update rust nightly version This fixes crc32fast 1.4.0 --- .github/workflows/ci.yml | 4 ++-- rust-toolchain.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3735309..1010b37 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -25,7 +25,7 @@ "with": { "components": "clippy,rustc-codegen-cranelift", - "toolchain": "nightly-2024-01-22", + "toolchain": "nightly-2024-04-10", }, }, { @@ -110,7 +110,7 @@ "with": { "components": "clippy", - "toolchain": "nightly-2024-01-22", + "toolchain": "nightly-2024-04-10", }, }, { diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 525e084..1c9a3ce 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,2 +1,2 @@ [toolchain] -channel = "nightly-2024-01-22" +channel = "nightly-2024-04-10" From d764b602de2dc40e62dac4bc44d0b0088f88e645 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 13:43:24 +0000 Subject: [PATCH 084/103] build(deps): bump toml from 0.8.10 to 0.8.12 Bumps [toml](https://github.com/toml-rs/toml) from 0.8.10 to 0.8.12. - [Commits](https://github.com/toml-rs/toml/compare/toml-v0.8.10...toml-v0.8.12) --- updated-dependencies: - dependency-name: toml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 10 +++++----- Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8e36ec..334e16c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3503,14 +3503,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.10" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.6", + "toml_edit 0.22.9", ] [[package]] @@ -3535,9 +3535,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.6" +version = "0.22.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" dependencies = [ "indexmap", "serde", diff --git a/Cargo.toml b/Cargo.toml index 9bf2c7f..6118343 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,7 +43,7 @@ futures = "0.3.28" axum = { version = "0.7.4", features = ["ws"] } cpu-time = "1.0.0" deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } -toml = "0.8.10" +toml = "0.8.12" textnonce = "1.0.0" From 6ef47ae45d28396cf4b728b569f6da504928d178 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 13:43:49 +0000 Subject: [PATCH 085/103] build(deps): bump axum from 0.7.4 to 0.7.5 Bumps [axum](https://github.com/tokio-rs/axum) from 0.7.4 to 0.7.5. - [Release notes](https://github.com/tokio-rs/axum/releases) - [Changelog](https://github.com/tokio-rs/axum/blob/main/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/axum/compare/axum-v0.7.4...axum-v0.7.5) --- updated-dependencies: - dependency-name: axum dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 14 ++++++++++---- Cargo.toml | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8e36ec..0ce7475 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -197,9 +197,9 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "axum" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1236b4b292f6c4d6dc34604bb5120d85c3fe1d1aa596bd5cc52ca054d13e7b9e" +checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" dependencies = [ "async-trait", "axum-core", @@ -223,7 +223,7 @@ dependencies = [ "serde_path_to_error", "serde_urlencoded", "sha1", - "sync_wrapper", + "sync_wrapper 1.0.1", "tokio", "tokio-tungstenite", "tower", @@ -247,7 +247,7 @@ dependencies = [ "mime", "pin-project-lite", "rustversion", - "sync_wrapper", + "sync_wrapper 0.1.2", "tower-layer", "tower-service", "tracing", @@ -3312,6 +3312,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" + [[package]] name = "tap" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index 9bf2c7f..8f251c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ serde = { version = "1.0.197", features = ["derive"] } tokio = {version="1.36.0", features = ["full"]} base64 = "0.21.0" futures = "0.3.28" -axum = { version = "0.7.4", features = ["ws"] } +axum = { version = "0.7.5", features = ["ws"] } cpu-time = "1.0.0" deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } toml = "0.8.10" From f74d9937ba6b72222ed0fc74eef99e72edada23b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 13:44:13 +0000 Subject: [PATCH 086/103] build(deps): bump prost from 0.12.3 to 0.12.4 Bumps [prost](https://github.com/tokio-rs/prost) from 0.12.3 to 0.12.4. - [Release notes](https://github.com/tokio-rs/prost/releases) - [Commits](https://github.com/tokio-rs/prost/compare/v0.12.3...v0.12.4) --- updated-dependencies: - dependency-name: prost dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 10 +++++----- Cargo.toml | 2 +- protobuf/Cargo.toml | 2 +- services/Cargo.toml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8e36ec..4b3a88c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2052,9 +2052,9 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" dependencies = [ "bytes", "prost-derive", @@ -2084,12 +2084,12 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.12.0", "proc-macro2", "quote", "syn 2.0.48", diff --git a/Cargo.toml b/Cargo.toml index 9bf2c7f..a2632dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ tracing-subscriber = { version = "0.3.18", features = ["tracing-log"]} futures-channel = "0.3.26" futures-util = "0.3.26" log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } -prost = "0.12.3" +prost = "0.12.4" prost-types = "0.12.3" serde_json = "1.0.115" serde = { version = "1.0.197", features = ["derive"] } diff --git a/protobuf/Cargo.toml b/protobuf/Cargo.toml index dfc462a..e4ac5d2 100644 --- a/protobuf/Cargo.toml +++ b/protobuf/Cargo.toml @@ -10,7 +10,7 @@ name = "protobuf" path = "src/lib.rs" [dependencies] -prost = "0.12.3" +prost = "0.12.4" prost-types = "0.12.3" [build-dependencies] diff --git a/services/Cargo.toml b/services/Cargo.toml index 4c55d5f..9859860 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -14,7 +14,7 @@ futures-util = "0.3.28" goval = { package = "protobuf", path = "../protobuf"} notify-debouncer-full = { version = "0.3.1", default-features = false } portable-pty = "0.8.1" -prost = "0.12.3" +prost = "0.12.4" prost-types = "0.12.3" ropey = "1.6.0" serde = "1.0.197" From 62db57e391114a2798c4f06916e2b6c6a2089f26 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 13:44:41 +0000 Subject: [PATCH 087/103] build(deps): bump async-trait from 0.1.77 to 0.1.80 Bumps [async-trait](https://github.com/dtolnay/async-trait) from 0.1.77 to 0.1.80. - [Release notes](https://github.com/dtolnay/async-trait/releases) - [Commits](https://github.com/dtolnay/async-trait/compare/0.1.77...0.1.80) --- updated-dependencies: - dependency-name: async-trait dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- services/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8e36ec..41fae5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -161,9 +161,9 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", diff --git a/services/Cargo.toml b/services/Cargo.toml index 4c55d5f..61794c8 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] anyhow = "1.0.81" -async-trait = "0.1.68" +async-trait = "0.1.80" crc32fast = { version = "1.4.0", features = ["nightly"] } deadqueue = { version = "0.2.4", default-features = false, features = ["unlimited"] } futures-util = "0.3.28" From 3bd1b263731ca29a9bf76c865cdfcebe5deb0949 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 13:45:10 +0000 Subject: [PATCH 088/103] build(deps): bump chrono from 0.4.34 to 0.4.38 Bumps [chrono](https://github.com/chronotope/chrono) from 0.4.34 to 0.4.38. - [Release notes](https://github.com/chronotope/chrono/releases) - [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md) - [Commits](https://github.com/chronotope/chrono/compare/v0.4.34...v0.4.38) --- updated-dependencies: - dependency-name: chrono dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8e36ec..5871b1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -420,9 +420,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "chrono" -version = "0.4.34" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", diff --git a/Cargo.toml b/Cargo.toml index 9bf2c7f..3b1bab8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,7 @@ toml = "0.8.10" textnonce = "1.0.0" -chrono = { version = "0.4.34", default-features = false, features = ["std", "libc", "clock"], optional = true } +chrono = { version = "0.4.38", default-features = false, features = ["std", "libc", "clock"], optional = true } chrono-tz = { version = "0.9.0", optional = true } From 51c895b6e99240a3f224664469e33fa6a4d044ea Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Tue, 16 Apr 2024 18:15:27 -0700 Subject: [PATCH 089/103] refactor(server): Remove `LazyLock`'s from function arguments Opting instead to just import and use the `LazyLock`. This makes it easier to make small updates to the type signature of any of the `LazyLock`'s. --- src/goval_server.rs | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/src/goval_server.rs b/src/goval_server.rs index d01516d..fbaf9a3 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -66,7 +66,7 @@ pub async fn start_server() -> Result<()> { let max_channel = Mutex::new(0); while let Some(message) = rx.recv().await { - handle_message(message, &SESSION_MAP, &max_channel).await; + handle_message(message, &max_channel).await; } }); @@ -126,15 +126,7 @@ async fn wsv2( ws.on_upgrade(move |socket| on_wsv2_upgrade(socket, token, state, addr)) } -async fn handle_message( - message: IPCMessage, - session_map: &LazyLock< - tokio::sync::RwLock< - std::collections::HashMap>, - >, - >, - max_channel: &Mutex, -) { +async fn handle_message(message: IPCMessage, max_channel: &Mutex) { let cmd: Command = message.clone().command; let cmd_body = match cmd.body { @@ -155,7 +147,7 @@ async fn handle_message( ..Default::default() }; - if let Some(sender) = session_map.read().await.get(&message.session) { + if let Some(sender) = SESSION_MAP.read().await.get(&message.session) { match sender.send(message.replace_cmd(pong)) { Ok(_) => {} Err(err) => { @@ -167,7 +159,7 @@ async fn handle_message( } } goval::command::Body::OpenChan(open_chan) => { - if let Err(err) = open_channel(open_chan, message, max_channel, session_map).await { + if let Err(err) = open_channel(open_chan, message, max_channel).await { error!(?err, "Error in open chan handler") } } @@ -210,11 +202,6 @@ async fn open_channel( open_chan: OpenChannel, message: IPCMessage, max_channel: &Mutex, - session_map: &LazyLock< - tokio::sync::RwLock< - std::collections::HashMap>, - >, - >, ) -> Result<()> { let searcher: &str = &open_chan.service; if homeval_services::IMPLEMENTED_SERVICES.contains(&searcher) { @@ -303,7 +290,7 @@ async fn open_channel( protocol_error.r#ref.clone_from(&message.command.r#ref); protocol_error.channel = 0; - session_map + SESSION_MAP .read() .await .get(&message.session) @@ -324,7 +311,7 @@ async fn open_channel( open_chan_res.r#ref.clone_from(&message.command.r#ref); open_chan_res.channel = 0; - session_map + SESSION_MAP .read() .await .get(&message.session) From 1af2d1446ecd51bfca8fe805aaf9717b1de87ef4 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Tue, 16 Apr 2024 18:24:23 -0700 Subject: [PATCH 090/103] refactor(services): Rewrite Presence#detach to not make an unnecessary clone of all users --- services/src/lib.rs | 2 ++ services/src/presence.rs | 28 +++++++++++++++------------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/services/src/lib.rs b/services/src/lib.rs index 71dcccb..438443c 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -1,3 +1,5 @@ +#![feature(extract_if)] + mod chat; mod dotreplit; mod exec; diff --git a/services/src/presence.rs b/services/src/presence.rs index 0e8338c..1db9a16 100644 --- a/services/src/presence.rs +++ b/services/src/presence.rs @@ -7,7 +7,7 @@ use std::{ collections::HashMap, time::{SystemTime, UNIX_EPOCH}, }; -use tracing::{info, warn}; +use tracing::{debug, trace, warn}; use super::traits; use anyhow::{format_err, Result}; @@ -139,17 +139,22 @@ impl traits::Service for Presence { async fn detach(&mut self, info: &super::types::ChannelInfo, session: SessionID) -> Result<()> { self.files.remove(&session); - let mut part = goval::Command::default(); let mut flag = false; - let users = self.users.clone(); - for (idx, user) in users.iter().enumerate() { - if user.session == session.0 { - flag = true; - part.body = Some(goval::command::Body::Part(user.clone())); - self.users.swap_remove(idx); - break; - } + for user in self.users.extract_if(|user| user.session == session.0) { + let part = goval::Command { + body: Some(goval::command::Body::Part(user.clone())), + ..Default::default() + }; + + trace!(%session, "Sending depart notification"); + + info.send(part, SendSessions::EveryoneExcept(session)) + .await?; + + debug!(?user, "Sent depart notification"); + + flag = true; } if !flag { @@ -159,9 +164,6 @@ impl traits::Service for Presence { )); } - info!(?part, "Presence#detach"); - info.send(part, SendSessions::EveryoneExcept(session)) - .await?; Ok(()) } } From 6b60a6d1980af01546f563ee1e71bd2842d59024 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Tue, 16 Apr 2024 18:36:02 -0700 Subject: [PATCH 091/103] refactor(services,dotreplit): Use clone_from when converting the DotReplit struct to goval message version --- services/src/dotreplit.rs | 2 +- services/src/types/config.rs | 87 ++++++++++++++++++------------------ 2 files changed, 45 insertions(+), 44 deletions(-) diff --git a/services/src/dotreplit.rs b/services/src/dotreplit.rs index 1dfb616..d8600b2 100644 --- a/services/src/dotreplit.rs +++ b/services/src/dotreplit.rs @@ -22,7 +22,7 @@ impl traits::Service for DotReplit { match body { goval::command::Body::DotReplitGetRequest(_) => { let mut dotreplit = goval::Command::default(); - let inner: goval::DotReplit = _info.dotreplit.read().await.clone().into(); + let inner: goval::DotReplit = (&*_info.dotreplit.read().await).into(); dotreplit.body = Some(goval::command::Body::DotReplitGetResponse( goval::DotReplitGetResponse { diff --git a/services/src/types/config.rs b/services/src/types/config.rs index dfa7b2d..e5daae6 100644 --- a/services/src/types/config.rs +++ b/services/src/types/config.rs @@ -16,7 +16,7 @@ pub use serde::{Deserialize, Serialize}; pub mod toolchain { use super::*; - #[derive(Serialize, Deserialize, Clone, Debug)] + #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct ToolchainConfigs { pub entrypoint: Option, @@ -36,7 +36,7 @@ pub mod toolchain { } */ - #[derive(Serialize, Deserialize, Clone, Debug)] + #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct RunOption { pub id: Option, @@ -56,7 +56,7 @@ pub mod toolchain { } */ - #[derive(Serialize, Deserialize, Clone, Debug)] + #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct DebuggerOption { pub id: Option, @@ -76,7 +76,7 @@ pub mod toolchain { } */ - #[derive(Serialize, Deserialize, Clone, Debug)] + #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct LanguageServerOption { pub id: Option, @@ -94,7 +94,7 @@ pub mod toolchain { } */ - #[derive(Serialize, Deserialize, Clone, Debug)] + #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct FileTypeAttrs { pub extensions: Vec, @@ -114,7 +114,7 @@ pub mod toolchain { } */ - #[derive(Serialize, Deserialize, Clone, Debug)] + #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct PackagerOption { pub id: Option, @@ -137,7 +137,7 @@ pub mod dotreplit { map languages = 9; repeated string hidden = 11; */ - #[derive(Serialize, Deserialize, Clone, Debug)] + #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct DotReplit { pub run: Option, @@ -147,36 +147,36 @@ pub mod dotreplit { pub hidden: Option>, } - impl From for goval::DotReplit { - fn from(val: DotReplit) -> Self { + impl From<&DotReplit> for goval::DotReplit { + fn from(val: &DotReplit) -> Self { let mut ret = goval::DotReplit::default(); - if let Some(run) = val.run { + if let Some(run) = &val.run { // let mut inner = goval::Exec::default(); // inner.args = vec!["sh".into(), "-c".into(), run]; ret.run = Some(run.into()); } - if let Some(lang) = val.language { - ret.language = lang; + if let Some(lang) = &val.language { + ret.language.clone_from(lang); } - if let Some(entrypoint) = val.entrypoint { - ret.entrypoint = entrypoint; + if let Some(entrypoint) = &val.entrypoint { + ret.entrypoint.clone_from(entrypoint); } - if let Some(languages) = val.languages { + if let Some(languages) = &val.languages { let mut inner = HashMap::new(); for (lang, data) in languages.iter() { - inner.insert(lang.into(), data.clone().into()); + inner.insert(lang.into(), data.into()); } ret.languages = inner } - if let Some(hidden) = val.hidden { - ret.hidden = hidden; + if let Some(hidden) = &val.hidden { + ret.hidden.clone_from(hidden); } ret @@ -190,7 +190,7 @@ pub mod dotreplit { } */ - #[derive(Serialize, Deserialize, Clone, Debug)] + #[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct DotReplitLanguage { pub pattern: Option, @@ -198,19 +198,19 @@ pub mod dotreplit { pub language_server: Option, } - impl From for goval::DotReplitLanguage { - fn from(val: DotReplitLanguage) -> Self { + impl From<&DotReplitLanguage> for goval::DotReplitLanguage { + fn from(val: &DotReplitLanguage) -> Self { let mut ret = goval::DotReplitLanguage::default(); - if let Some(pattern) = val.pattern { - ret.pattern = pattern; + if let Some(pattern) = &val.pattern { + ret.pattern.clone_from(pattern); } - if let Some(syntax) = val.syntax { - ret.syntax = syntax; + if let Some(syntax) = &val.syntax { + ret.syntax.clone_from(syntax); } - if let Some(language_server) = val.language_server { + if let Some(language_server) = &val.language_server { ret.language_server = Some(language_server.into()); } @@ -227,7 +227,7 @@ message LanguageServerConfig { } */ -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct LanguageServerConfig { #[serde(rename = "start")] @@ -236,23 +236,24 @@ pub struct LanguageServerConfig { pub initialization_options_json: Option, } -impl From for goval::LanguageServerConfig { - fn from(val: LanguageServerConfig) -> Self { +impl From<&LanguageServerConfig> for goval::LanguageServerConfig { + fn from(val: &LanguageServerConfig) -> Self { let mut ret = goval::LanguageServerConfig::default(); - if let Some(start_command) = val.start_command { + if let Some(start_command) = &val.start_command { // let mut inner = goval::Exec::default(); // inner.args = vec!["sh".into(), "-c".into(), start_command]; // ret.start_command = Some(inner); ret.start_command = Some(start_command.into()); } - if let Some(configuration_json) = val.configuration_json { - ret.configuration_json = configuration_json; + if let Some(configuration_json) = &val.configuration_json { + ret.configuration_json.clone_from(configuration_json); } - if let Some(initialization_options_json) = val.initialization_options_json { - ret.initialization_options_json = initialization_options_json; + if let Some(initialization_options_json) = &val.initialization_options_json { + ret.initialization_options_json + .clone_from(initialization_options_json); }; ret @@ -275,14 +276,14 @@ message Exec { } */ -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Debug)] pub enum ExecLifecycle { NonBlocking, Stdin, Blocking, } -#[derive(Serialize, Deserialize, Clone, Debug)] +#[derive(Serialize, Deserialize, Debug)] #[serde(rename_all = "camelCase")] pub struct Exec { pub args: Option>, @@ -293,16 +294,16 @@ pub struct Exec { pub split_logs: Option, } -impl From for goval::Exec { - fn from(val: Exec) -> Self { +impl From<&Exec> for goval::Exec { + fn from(val: &Exec) -> Self { let mut ret = goval::Exec::default(); - if let Some(args) = val.args { - ret.args = args; + if let Some(args) = &val.args { + ret.args.clone_from(args); } - if let Some(env) = val.env { - ret.env = env; + if let Some(env) = &val.env { + ret.env.clone_from(env); } if let Some(blocking) = val.blocking { @@ -317,7 +318,7 @@ impl From for goval::Exec { ret.split_logs = split_logs; } - if let Some(lifecycle) = val.lifecycle { + if let Some(lifecycle) = &val.lifecycle { ret.lifecycle = match lifecycle { ExecLifecycle::NonBlocking => goval::exec::Lifecycle::NonBlocking, ExecLifecycle::Blocking => goval::exec::Lifecycle::Blocking, From f4470b13bd3cc08adb966770cde3ce7efa3be909 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Tue, 16 Apr 2024 18:50:47 -0700 Subject: [PATCH 092/103] refactor(repldb): Avoid cloning entire hashmap and just use drain instead --- src/repldb_server.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/repldb_server.rs b/src/repldb_server.rs index 5ecff11..3fce74b 100644 --- a/src/repldb_server.rs +++ b/src/repldb_server.rs @@ -43,15 +43,15 @@ pub async fn start_server() -> Result<()> { Ok(()) } -async fn set_value(Form(data): Form>) -> StatusCode { +async fn set_value(Form(mut data): Form>) -> StatusCode { let database = crate::DATABASE .get() .expect("DATABASE is known to be set or else repldb server is disabled"); - for (key, value) in data.iter() { + for (key, value) in data.drain() { let active: repldb::ActiveModel = repldb::ActiveModel { - key: sea_orm::ActiveValue::Set(key.clone()), - value: sea_orm::ActiveValue::Set(value.clone()), + key: sea_orm::ActiveValue::Set(key), + value: sea_orm::ActiveValue::Set(value), }; let result = repldb::Entity::insert(active) From 3c84111858b7076d3eddbaa11089fd12e117afb9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 19:53:24 +0000 Subject: [PATCH 093/103] build(deps): bump rustls from 0.21.10 to 0.21.11 Bumps [rustls](https://github.com/rustls/rustls) from 0.21.10 to 0.21.11. - [Release notes](https://github.com/rustls/rustls/releases) - [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md) - [Commits](https://github.com/rustls/rustls/compare/v/0.21.10...v/0.21.11) --- updated-dependencies: - dependency-name: rustls dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7f7705d..2dc399d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2391,9 +2391,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" dependencies = [ "ring", "rustls-webpki", From 206ea8be863e5fc12919a9ffc176084d349577c3 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 22 Apr 2024 17:36:46 -0700 Subject: [PATCH 094/103] build(deps): Remove direct log dependency --- Cargo.lock | 137 ------------------------------------------------ Cargo.toml | 1 - src/database.rs | 4 +- 3 files changed, 2 insertions(+), 140 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8e36ec..766753b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -708,15 +708,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "erased-serde" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55d05712b2d8d88102bc9868020c9e5c7a1f5527c452b9b97450a1d006140ba7" -dependencies = [ - "serde", -] - [[package]] name = "errno" version = "0.3.8" @@ -1116,7 +1107,6 @@ dependencies = [ "hyper", "hyper-tls", "hyper-util", - "log", "migration", "pasetors", "prost", @@ -1426,10 +1416,6 @@ name = "log" version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" -dependencies = [ - "serde", - "value-bag", -] [[package]] name = "matchers" @@ -2673,15 +2659,6 @@ dependencies = [ "syn 2.0.48", ] -[[package]] -name = "serde_fmt" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" -dependencies = [ - "serde", -] - [[package]] name = "serde_json" version = "1.0.115" @@ -3194,84 +3171,6 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" -[[package]] -name = "sval" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1604e9ab506f4805bc62d2868c6d20f23fa6ced4c7cfe695a1d20589ba5c63d0" - -[[package]] -name = "sval_buffer" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2831b6451148d344f612016d4277348f7721b78a0869a145fd34ef8b06b3fa2e" -dependencies = [ - "sval", - "sval_ref", -] - -[[package]] -name = "sval_dynamic" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238ac5832a23099a413ffd22e66f7e6248b9af4581b64c758ca591074be059fc" -dependencies = [ - "sval", -] - -[[package]] -name = "sval_fmt" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8474862431bac5ac7aee8a12597798e944df33f489c340e17e886767bda0c4e" -dependencies = [ - "itoa", - "ryu", - "sval", -] - -[[package]] -name = "sval_json" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8f348030cc3d2a11eb534145600601f080cf16bf9ec0783efecd2883f14c21e" -dependencies = [ - "itoa", - "ryu", - "sval", -] - -[[package]] -name = "sval_nested" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6659c3f6be1e5e99dc7c518877f48a8a39088ace2504b046db789bd78ce5969d" -dependencies = [ - "sval", - "sval_buffer", - "sval_ref", -] - -[[package]] -name = "sval_ref" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829ad319bd82d0da77be6f3d547623686c453502f8eebdeb466cfa987972bd28" -dependencies = [ - "sval", -] - -[[package]] -name = "sval_serde" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9da6c3efaedf8b8c0861ec5343e8e8c51d838f326478623328bd8728b79bca" -dependencies = [ - "serde", - "sval", - "sval_nested", -] - [[package]] name = "syn" version = "1.0.109" @@ -3760,42 +3659,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" -[[package]] -name = "value-bag" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cdbaf5e132e593e9fc1de6a15bbec912395b11fb9719e061cf64f804524c503" -dependencies = [ - "value-bag-serde1", - "value-bag-sval2", -] - -[[package]] -name = "value-bag-serde1" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92cad98b1b18d06b6f38b3cd04347a9d7a3a0111441a061f71377fb6740437e4" -dependencies = [ - "erased-serde", - "serde", - "serde_fmt", -] - -[[package]] -name = "value-bag-sval2" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc7271d6b3bf58dd2e610a601c0e159f271ffdb7fbb21517c40b52138d64f8e" -dependencies = [ - "sval", - "sval_buffer", - "sval_dynamic", - "sval_fmt", - "sval_json", - "sval_ref", - "sval_serde", -] - [[package]] name = "vcpkg" version = "0.2.15" diff --git a/Cargo.toml b/Cargo.toml index 9bf2c7f..2bca5fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,6 @@ tracing-futures = "0.2.5" tracing-subscriber = { version = "0.3.18", features = ["tracing-log"]} futures-channel = "0.3.26" futures-util = "0.3.26" -log = { version = "0.4.17", features = ["kv_unstable", "kv_unstable_serde"] } prost = "0.12.3" prost-types = "0.12.3" serde_json = "1.0.115" diff --git a/src/database.rs b/src/database.rs index 07e71fa..c0fa3ac 100644 --- a/src/database.rs +++ b/src/database.rs @@ -3,7 +3,7 @@ use migration::MigratorTrait; use sea_orm::{ConnectOptions, Database}; use std::time::Duration; use tokio::sync::OnceCell; -use tracing::{debug, warn}; +use tracing::{debug, log::LevelFilter, warn}; pub static DATABASE: OnceCell = OnceCell::const_new(); @@ -22,7 +22,7 @@ pub async fn setup() -> Result<()> { let connect_options = ConnectOptions::new(db_url) .acquire_timeout(Duration::from_secs(5)) - .sqlx_logging_level(log::LevelFilter::Trace) + .sqlx_logging_level(LevelFilter::Trace) .to_owned(); debug!("Connecting to database"); From 4f8a85fa51df7514f59a505e624fb73c9bed95a0 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Mon, 22 Apr 2024 17:55:38 -0700 Subject: [PATCH 095/103] refactor(server): Use clippy::pedantic lint config --- src/goval_server.rs | 64 +++++++++++------------ src/main.rs | 3 +- src/parse_paseto.rs | 13 +++-- src/repldb_server.rs | 17 +++--- src/replspace_server.rs | 113 ++++++++++++++++++---------------------- 5 files changed, 100 insertions(+), 110 deletions(-) diff --git a/src/goval_server.rs b/src/goval_server.rs index fbaf9a3..f063dc6 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -66,7 +66,7 @@ pub async fn start_server() -> Result<()> { let max_channel = Mutex::new(0); while let Some(message) = rx.recv().await { - handle_message(message, &max_channel).await; + Box::pin(handle_message(message, &max_channel)).await; } }); @@ -110,9 +110,9 @@ async fn on_wsv2_upgrade(socket: WebSocket, token: String, state: AppState, addr ) .await { - Ok(_) => {} + Ok(()) => {} Err(err) => { - error!(?err, "accept_connection errored") + error!(?err, "accept_connection errored"); } }; } @@ -149,18 +149,18 @@ async fn handle_message(message: IPCMessage, max_channel: &Mutex) { if let Some(sender) = SESSION_MAP.read().await.get(&message.session) { match sender.send(message.replace_cmd(pong)) { - Ok(_) => {} + Ok(()) => {} Err(err) => { error!(?err, "Error occured while sending Pong"); } } } else { - error!("Missing session queue when sending Pong") + error!("Missing session queue when sending Pong"); } } goval::command::Body::OpenChan(open_chan) => { if let Err(err) = open_channel(open_chan, message, max_channel).await { - error!(?err, "Error in open chan handler") + error!(?err, "Error in open chan handler"); } } @@ -168,10 +168,10 @@ async fn handle_message(message: IPCMessage, max_channel: &Mutex) { // TODO: follow close_chan.action tokio::spawn(async move { match detach_channel(ChannelID(close_chan.id), message.session, true).await { - Ok(_) => {} + Ok(()) => {} Err(err) => { error!(%err, session = %message.session, channel = close_chan.id, - "Error occured while detaching from channel") + "Error occured while detaching from channel"); } } }); @@ -198,6 +198,7 @@ async fn handle_message(message: IPCMessage, max_channel: &Mutex) { } } +#[allow(clippy::too_many_lines)] async fn open_channel( open_chan: OpenChannel, message: IPCMessage, @@ -218,7 +219,7 @@ async fn open_channel( let metadata = CHANNEL_METADATA.read().await; for (id, channel) in metadata.iter() { if channel.name.is_some() - && channel.name.clone().unwrap_or("".to_string()) == open_chan.name + && channel.name.clone().unwrap_or_default() == open_chan.name && channel.service.clone() == open_chan.service { found = true; @@ -237,16 +238,16 @@ async fn open_channel( channel_id_held = channel_id; drop(max_channel); - let _channel_name = if !open_chan.name.is_empty() { - Some(open_chan.name) - } else { + let channel_name = if open_chan.name.is_empty() { None + } else { + Some(open_chan.name) }; let service_data = ServiceMetadata { service: service.clone(), id: channel_id, - name: _channel_name.clone(), + name: channel_name.clone(), }; trace!(channel = %channel_id, "Awaiting queue write"); @@ -267,14 +268,14 @@ async fn open_channel( let channel = homeval_services::Channel::new( channel_id, service, - _channel_name, + channel_name, DOTREPLIT_CONFIG.clone(), CHILD_PROCS_ENV_BASE.clone(), writer, ) .await .expect("TODO: Deal with this"); - channel.start(reader).await; + Box::pin(channel.start(reader)).await; }); found = true; } @@ -282,11 +283,11 @@ async fn open_channel( if !found { error!("Couldnt make channel"); let mut protocol_error = goval::Command::default(); - let _inner = goval::ProtocolError { + let inner = goval::ProtocolError { text: "Could not create / attach channel".to_string(), }; - protocol_error.body = Some(goval::command::Body::ProtocolError(_inner)); + protocol_error.body = Some(goval::command::Body::ProtocolError(inner)); protocol_error.r#ref.clone_from(&message.command.r#ref); protocol_error.channel = 0; @@ -301,13 +302,13 @@ async fn open_channel( } let mut open_chan_res = goval::Command::default(); - let _open_res = goval::OpenChannelRes { + let open_res = goval::OpenChannelRes { state: goval::open_channel_res::State::Created.into(), id: channel_id_held.into(), ..Default::default() }; - open_chan_res.body = Some(goval::command::Body::OpenChanRes(_open_res)); + open_chan_res.body = Some(goval::command::Body::OpenChanRes(open_res)); open_chan_res.r#ref.clone_from(&message.command.r#ref); open_chan_res.channel = 0; @@ -363,7 +364,7 @@ async fn open_channel( warn!( service = open_chan.service, "Missing service requested by openChan" - ) + ); } Ok(()) } @@ -485,12 +486,12 @@ async fn accept_connection( SESSION_CHANNELS.write().await.insert(session, vec![]); tokio::spawn(async move { - while let Some(_msg) = read.next().await { - match _msg { + while let Some(msg_res) = read.next().await { + match msg_res { Ok(msg) => match msg { WsMessage::Binary(buf) => { - let _message: anyhow::Result = buf.try_into(); - let message = match _message { + let ipc_message: anyhow::Result = buf.try_into(); + let message = match ipc_message { Ok(mut msg) => { msg.session = session; msg @@ -502,19 +503,18 @@ async fn accept_connection( }; if let Err(err) = propagate.send(message) { - error!(%session, ?err, "An error occured when enqueing message to global message queue") + error!(%session, ?err, "An error occured when enqueing message to global message queue"); } } WsMessage::Close(_) => { warn!(%session, "CLOSING SESSION"); - for _channel in SESSION_CHANNELS.read().await.get(&session).unwrap().iter() - { - let channel = *_channel; + for channel in SESSION_CHANNELS.read().await.get(&session).unwrap() { + let channel = *channel; tokio::spawn(async move { match detach_channel(channel, session, true).await { - Ok(_) => {} + Ok(()) => {} Err(err) => { - error!(%err, %session, %channel, "Error occured while detaching from channel") + error!(%err, %session, %channel, "Error occured while detaching from channel"); } } }); @@ -536,13 +536,13 @@ async fn accept_connection( while let Some(i) = sent.recv().await { match write.send(WsMessage::Binary(i.to_bytes())).await { - Ok(_) => {} + Ok(()) => {} Err(err) => { error!( session = %i.session, ?err, "An error occured while sending a message" - ) + ); } } } diff --git a/src/main.rs b/src/main.rs index 36e8146..30c7c96 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ #![feature(lazy_cell)] +#![warn(clippy::pedantic)] use std::sync::LazyLock; use std::time::Instant; @@ -30,7 +31,7 @@ static CPU_STATS: LazyLock> = pub static DOTREPLIT_CONFIG: LazyLock>> = LazyLock::new(|| { Arc::new(RwLock::const_new( - toml::from_str(&std::fs::read_to_string(".replit").unwrap_or("".to_string())).unwrap(), + toml::from_str(&std::fs::read_to_string(".replit").unwrap_or_default()).unwrap(), )) }); diff --git a/src/parse_paseto.rs b/src/parse_paseto.rs index 975b484..360a45b 100644 --- a/src/parse_paseto.rs +++ b/src/parse_paseto.rs @@ -53,9 +53,9 @@ async fn init_keys() -> Result> { Client::builder(TokioExecutor::new()) .build::, Collected>(https); - let mut _body = client.get(hyper::Uri::try_from(key_get)?).await?; + let mut body = client.get(hyper::Uri::try_from(key_get)?).await?; - let body = _body.body_mut().collect().await?.to_bytes(); + let body = body.body_mut().collect().await?.to_bytes(); Ok(serde_json::from_slice(&body)?) } @@ -74,8 +74,8 @@ async fn parse_verify(input: &str) -> Result<(Vec, bool)> { } }; - let _authority = general_purpose::STANDARD.decode(token.untrusted_footer())?; - let authority = goval::GovalSigningAuthority::decode(_authority.as_slice())?; + let authority = general_purpose::STANDARD.decode(token.untrusted_footer())?; + let authority = goval::GovalSigningAuthority::decode(authority.as_slice())?; let key_id; @@ -115,7 +115,7 @@ async fn parse_verify(input: &str) -> Result<(Vec, bool)> { Err(err) => { return Err(Error::new( std::io::ErrorKind::InvalidData, - format!("Paseto invalid: `{:#?}`", err), + format!("Paseto invalid: `{err:#?}`"), ) .into()); } @@ -149,8 +149,7 @@ pub async fn parse(token: &str) -> Result { } } - let _inner = general_purpose::STANDARD.decode(msg)?; - let inner = goval::token::ReplToken::decode(_inner.as_slice())?; + let inner = goval::token::ReplToken::decode(general_purpose::STANDARD.decode(msg)?.as_slice())?; match inner.presenced { Some(user) => Ok(ClientInfo { diff --git a/src/repldb_server.rs b/src/repldb_server.rs index 3fce74b..86b8092 100644 --- a/src/repldb_server.rs +++ b/src/repldb_server.rs @@ -84,12 +84,12 @@ async fn get_value(Path(key): Path) -> (StatusCode, String) { match result { Ok(value) => match value { - None => (StatusCode::NOT_FOUND, "".to_string()), + None => (StatusCode::NOT_FOUND, String::new()), Some(data) => (StatusCode::OK, data.value), }, Err(err) => { error!(?err, "Encountered error reading key from database"); - (StatusCode::INTERNAL_SERVER_ERROR, "".to_string()) + (StatusCode::INTERNAL_SERVER_ERROR, String::new()) } } } @@ -122,9 +122,8 @@ struct ListKeys { } async fn list_keys(Query(__prefix): Query) -> (StatusCode, String) { - let prefix = match __prefix.prefix { - Some(prefix) => prefix, - None => return (StatusCode::OK, "".to_string()), + let Some(prefix) = __prefix.prefix else { + return (StatusCode::OK, String::new()); }; let database = crate::DATABASE @@ -138,20 +137,20 @@ async fn list_keys(Query(__prefix): Query) -> (StatusCode, String) { match result { Ok(value) => { - let mut keys = "".to_string(); + let mut keys = String::new(); for (index, info) in value.iter().enumerate() { if index != 0 { - keys += "\n" + keys += "\n"; } - keys += &info.key + keys += &info.key; } (StatusCode::OK, keys) } Err(err) => { error!(?err, "Encountered error listing keys in database"); - (StatusCode::INTERNAL_SERVER_ERROR, "".to_string()) + (StatusCode::INTERNAL_SERVER_ERROR, String::new()) } } } diff --git a/src/replspace_server.rs b/src/replspace_server.rs index 5467774..a547694 100644 --- a/src/replspace_server.rs +++ b/src/replspace_server.rs @@ -48,9 +48,9 @@ struct GithubTokenReq { channel: i32, } -async fn get_gh_token(_query: Option>) -> (StatusCode, Json) { +async fn get_gh_token(query: Option>) -> (StatusCode, Json) { let session; - if let Some(query) = _query { + if let Some(query) = query { debug!(channel = query.channel, "Got git askpass"); let last_session = crate::LAST_SESSION_USING_CHANNEL.read().await; @@ -78,35 +78,29 @@ async fn get_gh_token(_query: Option>) -> (StatusCode, Jso let msg = rx.recv().await; rx.close(); - let res = match msg { - Some(token) => token, - None => { - error!("rx#recv() returned None in gh get token"); - return ( - StatusCode::INTERNAL_SERVER_ERROR, - Json(GithubTokenRes { - status: ReplspaceStatus::Err, - token: None, - }), - ); - } + let Some(res) = msg else { + error!("rx#recv() returned None in gh get token"); + return ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(GithubTokenRes { + status: ReplspaceStatus::Err, + token: None, + }), + ); }; - let token = match res { - ReplspaceMessage::GithubTokenRes(token) => token, - _ => { - error!( - result = ?res, - "Got unexpected result in replspace api github token fetcher" - ); - return ( - StatusCode::INTERNAL_SERVER_ERROR, - Json(GithubTokenRes { - status: ReplspaceStatus::Err, - token: None, - }), - ); - } + let ReplspaceMessage::GithubTokenRes(token) = res else { + error!( + result = ?res, + "Got unexpected result in replspace api github token fetcher" + ); + return ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(GithubTokenRes { + status: ReplspaceStatus::Err, + token: None, + }), + ); }; ( @@ -154,13 +148,13 @@ async fn open_file(Json(query): Json) -> (StatusCode, Json) -> (StatusCode, Json token, - None => { - error!("rx#none() returned none in replspace api open file fetcher"); - return ( - StatusCode::INTERNAL_SERVER_ERROR, - Json(OpenFileRes { - status: ReplspaceStatus::Err, - }), - ); - } + + let Some(res) = msg else { + error!("rx#none() returned none in replspace api open file fetcher"); + return ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(OpenFileRes { + status: ReplspaceStatus::Err, + }), + ); }; - match res { - ReplspaceMessage::OpenFileRes => ( + if let ReplspaceMessage::OpenFileRes = res { + ( StatusCode::OK, Json(OpenFileRes { status: ReplspaceStatus::Ok, }), - ), - _ => { - error!( - result = ?res, - "Got unexpected result in replspace api github token fetcher" - ); - ( - StatusCode::INTERNAL_SERVER_ERROR, - Json(OpenFileRes { - status: ReplspaceStatus::Err, - }), - ) - } + ) + } else { + error!( + result = ?res, + "Got unexpected result in replspace api github token fetcher" + ); + ( + StatusCode::INTERNAL_SERVER_ERROR, + Json(OpenFileRes { + status: ReplspaceStatus::Err, + }), + ) } } From 81ff08296df44a2b6c6601c3e0073bb68e805da7 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:32:22 -0700 Subject: [PATCH 096/103] refactor(services): Use clippy::pedantic lint config with some exceptions This commit also fixes all warnings generated by enabling these settings --- services/src/chat.rs | 6 +- services/src/exec.rs | 25 +++----- services/src/fsevents.rs | 34 +++++------ services/src/gcsfiles.rs | 10 +-- services/src/git.rs | 6 +- services/src/lib.rs | 53 +++++++++------- services/src/ot.rs | 98 +++++++++++++++--------------- services/src/output.rs | 36 +++++------ services/src/presence.rs | 28 ++++----- services/src/shell.rs | 16 ++--- services/src/types/channel_info.rs | 18 +++--- services/src/types/client.rs | 2 +- services/src/types/config.rs | 6 +- services/src/types/fs_watcher.rs | 48 +++++++++------ services/src/types/proc.rs | 18 +++--- services/src/types/pty.rs | 34 +++++------ 16 files changed, 219 insertions(+), 219 deletions(-) diff --git a/services/src/chat.rs b/services/src/chat.rs index 30f12e9..987f457 100644 --- a/services/src/chat.rs +++ b/services/src/chat.rs @@ -30,14 +30,12 @@ impl traits::Service for Chat { match body { goval::command::Body::ChatMessage(msg) => { - info.send(message, SendSessions::EveryoneExcept(session)) - .await?; + info.send(message, SendSessions::EveryoneExcept(session))?; self.history.push(msg); Ok(None) } goval::command::Body::ChatTyping(_) => { - info.send(message, SendSessions::EveryoneExcept(session)) - .await?; + info.send(message, SendSessions::EveryoneExcept(session))?; Ok(None) } _ => { diff --git a/services/src/exec.rs b/services/src/exec.rs index ff0a463..12a56c0 100644 --- a/services/src/exec.rs +++ b/services/src/exec.rs @@ -32,8 +32,7 @@ impl traits::Service for Exec { ..Default::default() }, crate::SendSessions::Everyone, - ) - .await?; + )?; return Ok(None); } @@ -45,19 +44,17 @@ impl traits::Service for Exec { ..Default::default() }, crate::SendSessions::Everyone, - ) - .await?; + )?; self.running = true; self.current_ref = message.r#ref; - Proc::new(exec.args, info.id, info.sender.clone(), Some(exec.env)).await?; + Proc::new(exec.args, info.id, info.sender.clone(), Some(&exec.env))?; info.send( goval::Command { body: Some(goval::command::Body::State(goval::State::Running.into())), ..Default::default() }, crate::SendSessions::Everyone, - ) - .await?; + )?; } } @@ -78,8 +75,7 @@ impl traits::Service for Exec { ..Default::default() }, crate::SendSessions::Everyone, - ) - .await?; + )?; } else { info.send( goval::Command { @@ -90,8 +86,7 @@ impl traits::Service for Exec { ..Default::default() }, crate::SendSessions::Everyone, - ) - .await?; + )?; } self.current_ref = String::new(); @@ -102,13 +97,12 @@ impl traits::Service for Exec { ..Default::default() }, crate::SendSessions::Everyone, - ) - .await?; + )?; if !self.queue.is_empty() { self.running = true; let item = self.queue.swap_remove(0); - Proc::new(item.0.args, info.id, info.sender.clone(), Some(item.0.env)).await?; + Proc::new(item.0.args, info.id, info.sender.clone(), Some(&item.0.env))?; self.current_ref = item.1; info.send( goval::Command { @@ -116,8 +110,7 @@ impl traits::Service for Exec { ..Default::default() }, crate::SendSessions::Everyone, - ) - .await?; + )?; } Ok(()) diff --git a/services/src/fsevents.rs b/services/src/fsevents.rs index 00738ac..e2abc9e 100644 --- a/services/src/fsevents.rs +++ b/services/src/fsevents.rs @@ -37,23 +37,20 @@ impl traits::Service for FSEvents { Some(body) => body, }; - match body { - goval::command::Body::SubscribeFile(subscribe) => { - let mut files = vec![]; - for file in subscribe.files { - files.push(file.path); - } - - self.watcher.watch(files).await?; - Ok(Some(goval::Command { - body: Some(goval::command::Body::Ok(goval::Ok {})), - ..Default::default() - })) - } - _ => { - warn!(cmd = ?message, "Unknown fs event command"); - Ok(None) + if let goval::command::Body::SubscribeFile(subscribe) = body { + let mut files = vec![]; + for file in subscribe.files { + files.push(file.path); } + + self.watcher.watch(files)?; + Ok(Some(goval::Command { + body: Some(goval::command::Body::Ok(goval::Ok {})), + ..Default::default() + })) + } else { + warn!(cmd = ?message, "Unknown fs event command"); + Ok(None) } } @@ -114,13 +111,12 @@ impl traits::Service for FSEvents { ..Default::default() }, crate::SendSessions::Everyone, - ) - .await?; + )?; Ok(()) } async fn shutdown(self: Box, _info: &super::types::ChannelInfo) -> Result<()> { - self.watcher.shutdown().await; + self.watcher.shutdown(); Ok(()) } } diff --git a/services/src/gcsfiles.rs b/services/src/gcsfiles.rs index bbaddfc..6d8b3a8 100644 --- a/services/src/gcsfiles.rs +++ b/services/src/gcsfiles.rs @@ -46,10 +46,10 @@ impl traits::Service for GCSFiles { } } - let mut ret = goval::Command::default(); + let mut ret_cmd = goval::Command::default(); let _inner = goval::Files { files: res }; - ret.body = Some(goval::command::Body::Files(_inner)); - Ok(Some(ret)) + ret_cmd.body = Some(goval::command::Body::Files(_inner)); + Ok(Some(ret_cmd)) } goval::command::Body::Mkdir(dir) => { fs::create_dir_all(dir.path).await?; @@ -107,9 +107,9 @@ impl traits::Service for GCSFiles { goval::command::Body::Remove(file) => { let stat = fs::metadata(&file.path).await?; if stat.is_dir() { - fs::remove_dir_all(&file.path).await? + fs::remove_dir_all(&file.path).await?; } else { - fs::remove_file(&file.path).await? + fs::remove_file(&file.path).await?; } let ret = goval::Command { diff --git a/services/src/git.rs b/services/src/git.rs index 6147f3e..2667ce1 100644 --- a/services/src/git.rs +++ b/services/src/git.rs @@ -82,8 +82,7 @@ impl traits::Service for Git { )), ..Default::default() }; - info.send(token_req, crate::SendSessions::Only(session)) - .await?; + info.send(token_req, crate::SendSessions::Only(session))?; self.replspace.insert(nonce, respond); } @@ -98,8 +97,7 @@ impl traits::Service for Git { )), ..Default::default() }; - info.send(token_req, crate::SendSessions::Only(session)) - .await?; + info.send(token_req, crate::SendSessions::Only(session))?; self.replspace.insert(nonce, respond); } diff --git a/services/src/lib.rs b/services/src/lib.rs index 438443c..78f4bbe 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -1,4 +1,19 @@ #![feature(extract_if)] +#![warn(clippy::pedantic, clippy::unwrap_used)] +#![allow( + clippy::module_name_repetitions, + clippy::must_use_candidate, + clippy::return_self_not_must_use, + + // TODO: investigate performance impact of i__::try_from + clippy::cast_possible_truncation, + clippy::cast_possible_wrap, + + // TODO: remove and fix these + clippy::missing_errors_doc, + clippy::missing_panics_doc, + clippy::too_many_lines +)] mod chat; mod dotreplit; @@ -26,7 +41,7 @@ pub use types::*; pub struct Channel { info: ChannelInfo, - _inner: Box, + inner: Box, } // Public functions @@ -56,27 +71,25 @@ impl Channel { "presence" => Box::new(presence::Presence::new()), "ot" => Box::new(ot::OT::new(sender).await?), "snapshot" => Box::new(snapshot::Snapshot {}), - "output" => Box::new(output::Output::new().await), - "shell" => Box::new(shell::Shell::new(&info).await?), + "output" => Box::new(output::Output::new()), + "shell" => Box::new(shell::Shell::new(&info)?), "toolchain" => Box::new(toolchain::Toolchain {}), "git" => Box::new(git::Git::new()), "exec" => Box::new(exec::Exec::new()), "dotreplit" => Box::new(dotreplit::DotReplit {}), "fsevents" => Box::new(fsevents::FSEvents::new(sender).await?), - "audio" => Box::new(stub::Stub {}), // Will never be supported - "null" => Box::new(stub::Stub {}), // This channel never does anything - "open" => Box::new(stub::Stub {}), // Stub until infra is set up to handle this + "audio" | "null" => Box::new(stub::Stub {}), // Audio will never be supported and null does nothing _ => return Err(format_err!("Unknown service: {}", service)), }; Ok(Channel { info, - _inner: channel, + inner: channel, }) } pub async fn start(mut self, mut read: tokio::sync::mpsc::UnboundedReceiver) { - if let Err(err) = self._inner.open(&self.info).await { + if let Err(err) = self.inner.open(&self.info).await { error!(%err, "Error encountered in Service::open"); } @@ -88,24 +101,22 @@ impl Channel { ChannelMessage::Detach(session) => self.detach(session).await, ChannelMessage::IPC(ipc) => self.message(ipc.command, ipc.session).await, ChannelMessage::ProcessDead(exit_code) => { - self._inner.proccess_died(&self.info, exit_code).await + self.inner.proccess_died(&self.info, exit_code).await } ChannelMessage::Replspace(session, msg, respond) => { - self._inner + self.inner .replspace(&self.info, msg, session, respond) .await } - ChannelMessage::Shutdown => match self._inner.shutdown(&self.info).await { - Ok(_) => break, + ChannelMessage::Shutdown => match self.inner.shutdown(&self.info).await { + Ok(()) => break, Err(err) => { error!(%err, "Error encountered in Service#shutdown"); break; } }, - ChannelMessage::FSEvent(event) => self._inner.fsevent(&self.info, event).await, - ChannelMessage::ExternalMessage(msg, sessions) => { - self.info.send(msg, sessions).await - } + ChannelMessage::FSEvent(event) => self.inner.fsevent(&self.info, event).await, + ChannelMessage::ExternalMessage(msg, sessions) => self.info.send(msg, sessions), }; if let Err(err) = result { @@ -119,12 +130,12 @@ impl Channel { impl Channel { async fn message(&mut self, message: goval::Command, session: SessionID) -> Result<()> { if let Some(mut msg) = self - ._inner + .inner .message(&self.info, message.clone(), session) .await? { msg.r#ref = message.r#ref; - self.info.send(msg, SendSessions::Only(session)).await? + self.info.send(msg, SendSessions::Only(session))?; } Ok(()) @@ -139,13 +150,13 @@ impl Channel { self.info.sessions.insert(session, client.clone()); self.info.clients.insert(session, sender.clone()); match self - ._inner + .inner .attach(&self.info, client, session, sender) .await? { None => {} Some(msg) => { - self.info.send(msg, SendSessions::Only(session)).await?; + self.info.send(msg, SendSessions::Only(session))?; } } Ok(()) @@ -154,7 +165,7 @@ impl Channel { async fn detach(&mut self, session: SessionID) -> Result<()> { self.info.sessions.retain(|sess, _| sess != &session); self.info.clients.retain(|sess, _| sess != &session); - self._inner.detach(&self.info, session).await?; + self.inner.detach(&self.info, session).await?; Ok(()) } } diff --git a/services/src/ot.rs b/services/src/ot.rs index 060bf8e..61e4d69 100644 --- a/services/src/ot.rs +++ b/services/src/ot.rs @@ -1,7 +1,7 @@ pub struct OT { crc32: u32, version: u32, - contents: ropey::Rope, + contents: Rope, path: String, cursors: HashMap, history: Vec, @@ -18,6 +18,7 @@ use crate::{client::ClientInfo, fs_watcher::FSWatcher, FSEvent, IPCMessage, Sess use super::traits; use anyhow::{format_err, Result}; use async_trait::async_trait; +use ropey::Rope; use similar::TextDiff; use tokio::fs; use tracing::{debug, error, trace, warn}; @@ -31,8 +32,8 @@ impl OT { let chan = OT { crc32: 0, version: 1, - contents: "".into(), - path: "".to_string(), + contents: Rope::new(), + path: String::new(), cursors: HashMap::new(), history: vec![], watcher, @@ -57,12 +58,16 @@ impl traits::Service for OT { if self.path.is_empty() { if let goval::command::Body::OtLinkFile(link_file) = body.clone() { - let path = link_file.file.unwrap().path; + let Some(goval::File { path, .. }) = link_file.file else { + return Err(format_err!( + "Session `{session}` sent OT::OtLinkFile without an attached file" + )); + }; + if (fs::metadata(path.clone()).await).is_err() { let error = goval::Command { body: Some(goval::command::Body::Error(format!( - "{}: no such file or directory", - path + "{path}: no such file or directory" ))), ..Default::default() }; @@ -80,10 +85,7 @@ impl traits::Service for OT { self.contents = file_contents.clone().into(); let timestamp = Some(prost_types::Timestamp { - seconds: SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs() as i64, + seconds: SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64, nanos: 0, }); @@ -98,7 +100,7 @@ impl traits::Service for OT { crc32, committed: timestamp, author: goval::ot_packet::Author::User.into(), - user_id: 23352071, + user_id: 23_352_071, nonce: 0, }; @@ -118,7 +120,7 @@ impl traits::Service for OT { }; link_response.body = Some(goval::command::Body::OtLinkFileResponse(_inner)); - self.watcher.watch(vec![path]).await?; + self.watcher.watch(vec![path])?; // let mut reader = self.watcher.get_event_reader().await; // let sending_map = self._sending_map.clone(); @@ -155,19 +157,25 @@ impl traits::Service for OT { // }); return Ok(Some(link_response)); - } else { - return Err(format_err!("Command sent before otLinkFile")); } + + return Err(format_err!("Command sent before otLinkFile")); } match body { goval::command::Body::Ot(ot) => { let mut cursor: usize = 0; - for op in ot.op.clone() { - match op.op_component.unwrap() { + for op in &ot.op { + let Some(component) = &op.op_component else { + return Err(format_err!( + "Session `{session}` sent an ot packet without components" + )); + }; + + match component { goval::ot_op_component::OpComponent::Skip(_skip) => { - let skip: usize = _skip.try_into()?; + let skip: usize = (*_skip).try_into()?; if skip + cursor > self.contents.len_chars() { let err = goval::Command { body: Some(goval::command::Body::Error( @@ -178,10 +186,10 @@ impl traits::Service for OT { return Ok(Some(err)); } - cursor += skip + cursor += skip; } goval::ot_op_component::OpComponent::Delete(_delete) => { - let delete: usize = _delete.try_into()?; + let delete: usize = (*_delete).try_into()?; if delete + cursor > self.contents.len_chars() { let err = goval::Command { body: Some(goval::command::Body::Error( @@ -192,10 +200,10 @@ impl traits::Service for OT { return Ok(Some(err)); } - self.contents.remove(cursor..(cursor + delete)) + self.contents.remove(cursor..(cursor + delete)); } goval::ot_op_component::OpComponent::Insert(insert) => { - self.contents.insert(cursor, &insert) + self.contents.insert(cursor, insert); } } } @@ -206,21 +214,18 @@ impl traits::Service for OT { let user_id; if ot.author == goval::ot_packet::Author::Ghostwriter as i32 { - user_id = 22261053 // https://replit.com/@ghostwriterai + user_id = 22_261_053; // https://replit.com/@ghostwriterai } else if let Some(user) = info.sessions.get(&session) { - user_id = user.id + user_id = user.id; } else { - user_id = 23054564 // https://replit.com/@homeval-user + user_id = 23_054_564; // https://replit.com/@homeval-user } let crc32 = crc32fast::hash(to_write.as_bytes()); self.crc32 = crc32; let committed = Some(prost_types::Timestamp { - seconds: SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs() as i64, + seconds: SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64, nanos: 0, }); @@ -242,7 +247,7 @@ impl traits::Service for OT { ..Default::default() }; - info.send(ot_notif, crate::SendSessions::Everyone).await?; + info.send(ot_notif, crate::SendSessions::Everyone)?; fs::write(&self.path, to_write).await?; @@ -261,8 +266,7 @@ impl traits::Service for OT { ..Default::default() }; - info.send(cursor_notif, crate::SendSessions::EveryoneExcept(session)) - .await?; + info.send(cursor_notif, crate::SendSessions::EveryoneExcept(session))?; Ok(None) } goval::command::Body::OtDeleteCursor(cursor) => { @@ -276,8 +280,7 @@ impl traits::Service for OT { info.send( cursor_delete_notif, crate::SendSessions::EveryoneExcept(session), - ) - .await?; + )?; Ok(None) } @@ -287,7 +290,7 @@ impl traits::Service for OT { let to = request.version_to as usize; for (index, item) in self.history.iter().enumerate() { if index >= from && index <= to { - packets.push(item.clone()) + packets.push(item.clone()); } } @@ -334,16 +337,13 @@ impl traits::Service for OT { let new_contents = String::from_utf8(new_contents).expect("TODO: Deal with this"); - let ops = diff(self.contents.to_string(), new_contents.clone()); + let ops = diff(&self.contents.to_string(), &new_contents); self.contents = new_contents.into(); self.crc32 = new_crc32; let committed = Some(prost_types::Timestamp { - seconds: SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs() as i64, + seconds: SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64, nanos: 0, }); @@ -365,7 +365,7 @@ impl traits::Service for OT { ..Default::default() }; - info.send(ot_notif, crate::SendSessions::Everyone).await?; + info.send(ot_notif, crate::SendSessions::Everyone)?; } Ok(()) } @@ -404,7 +404,7 @@ impl traits::Service for OT { let mut cursors = vec![]; for cursor in self.cursors.values() { - cursors.push(cursor.clone()) + cursors.push(cursor.clone()); } let _inner = goval::OtStatus { @@ -420,15 +420,15 @@ impl traits::Service for OT { } async fn shutdown(self: Box, _info: &super::types::ChannelInfo) -> Result<()> { - self.watcher.shutdown().await; + self.watcher.shutdown(); Ok(()) } } -fn diff(old_text: String, new_text: String) -> Vec { - let mut _differ = TextDiff::configure(); - let differ = _differ.timeout(Duration::from_secs(1)); - let diff = differ.diff_chars(&old_text, &new_text); +fn diff(old_text: &str, new_text: &str) -> Vec { + let mut differ_config: similar::TextDiffConfig = TextDiff::configure(); + let differ = differ_config.timeout(Duration::from_secs(1)); + let diff = differ.diff_chars(old_text, new_text); let mut parts: Vec = vec![]; let mut last_op: Option = None; @@ -439,7 +439,7 @@ fn diff(old_text: String, new_text: String) -> Vec { if let Some(goval::ot_op_component::OpComponent::Skip(amount)) = last_op.clone() { last_op = Some(goval::ot_op_component::OpComponent::Skip( amount + part.value().len() as u32, - )) + )); } else { new_op = Some(goval::ot_op_component::OpComponent::Skip( part.value().len() as u32, @@ -450,7 +450,7 @@ fn diff(old_text: String, new_text: String) -> Vec { if let Some(goval::ot_op_component::OpComponent::Delete(amount)) = last_op.clone() { last_op = Some(goval::ot_op_component::OpComponent::Delete( amount + part.value().len() as u32, - )) + )); } else { new_op = Some(goval::ot_op_component::OpComponent::Delete( part.value().len() as u32, @@ -461,7 +461,7 @@ fn diff(old_text: String, new_text: String) -> Vec { if let Some(goval::ot_op_component::OpComponent::Insert(same)) = last_op.clone() { last_op = Some(goval::ot_op_component::OpComponent::Insert( same + part.value(), - )) + )); } else { new_op = Some(goval::ot_op_component::OpComponent::Insert( part.value().to_string(), diff --git a/services/src/output.rs b/services/src/output.rs index acb15bf..dc215f2 100644 --- a/services/src/output.rs +++ b/services/src/output.rs @@ -41,8 +41,7 @@ impl traits::Service for Output { }; new_frame.body = Some(goval::command::Body::OutputBlockStartEvent(event)); - info.send(new_frame, crate::SendSessions::Only(session)) - .await?; + info.send(new_frame, crate::SendSessions::Only(session))?; pty.session_join(session, sender).await?; } @@ -98,16 +97,13 @@ impl traits::Service for Output { let mut env = HashMap::new(); env.insert("REPLIT_GIT_TOOLS_CHANNEL_FROM".into(), info.id.to_string()); - self.pty = Some( - Pty::start( - cmd, - info.id, - Arc::new(RwLock::new(info.clients.clone())), - info.sender.clone(), - Some(env), - ) - .await?, - ); + self.pty = Some(Pty::start( + cmd, + info.id, + Arc::new(RwLock::new(info.clients.clone())), + &info.sender, + Some(env), + )?); let mut new_frame = goval::Command::default(); @@ -121,25 +117,25 @@ impl traits::Service for Output { }; new_frame.body = Some(goval::command::Body::OutputBlockStartEvent(event)); - info.send(new_frame, crate::SendSessions::Everyone).await?; + info.send(new_frame, crate::SendSessions::Everyone)?; let status = goval::Command { body: Some(goval::command::Body::State(goval::State::Running.into())), ..Default::default() }; - info.send(status, crate::SendSessions::Everyone).await?; + info.send(status, crate::SendSessions::Everyone)?; } goval::command::Body::Clear(_) => { if let Some(pty) = &mut self.pty { pty.cancel().await?; } else { - warn!("Client tried to stop an already stopped pty") + warn!("Client tried to stop an already stopped pty"); } } goval::command::Body::Input(msg) => { if let Some(pty) = &mut self.pty { - pty.write(msg)?; + pty.write(&msg)?; } } goval::command::Body::ResizeTerm(_) => {} @@ -172,7 +168,7 @@ impl traits::Service for Output { }; end_frame.body = Some(goval::command::Body::OutputBlockEndEvent(event)); - info.send(end_frame, crate::SendSessions::Everyone).await?; + info.send(end_frame, crate::SendSessions::Everyone)?; if exit_code != 0 { let error = goval::Command { @@ -182,20 +178,20 @@ impl traits::Service for Output { ..Default::default() }; - info.send(error, crate::SendSessions::Everyone).await?; + info.send(error, crate::SendSessions::Everyone)?; } let status = goval::Command { body: Some(goval::command::Body::State(goval::State::Stopped.into())), ..Default::default() }; - info.send(status, crate::SendSessions::Everyone).await?; + info.send(status, crate::SendSessions::Everyone)?; Ok(()) } } impl Output { - pub async fn new() -> Output { + pub fn new() -> Output { Output { pty: None, start_time: None, diff --git a/services/src/presence.rs b/services/src/presence.rs index 1db9a16..79bb49b 100644 --- a/services/src/presence.rs +++ b/services/src/presence.rs @@ -44,8 +44,7 @@ impl traits::Service for Presence { ..Default::default() }; - info.send(follow_notif, SendSessions::Only(SessionID(follow.session))) - .await?; + info.send(follow_notif, SendSessions::Only(SessionID(follow.session)))?; Ok(None) } goval::command::Body::UnfollowUser(unfollow) => { @@ -59,20 +58,20 @@ impl traits::Service for Presence { info.send( unfollow_notif, SendSessions::Only(SessionID(unfollow.session)), - ) - .await?; + )?; Ok(None) } goval::command::Body::OpenFile(file) => { - let user = info.sessions.get(&session).unwrap(); + let Some(user) = info.sessions.get(&session) else { + return Err(format_err!( + "Session `{session}` who is not joined tried to send Presence::OpenFile" + )); + }; let mut file_notif = goval::Command::default(); let timestamp = Some(prost_types::Timestamp { - seconds: SystemTime::now() - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs() as i64, + seconds: SystemTime::now().duration_since(UNIX_EPOCH)?.as_secs() as i64, nanos: 0, }); @@ -85,8 +84,7 @@ impl traits::Service for Presence { file_notif.body = Some(goval::command::Body::FileOpened(_inner)); - info.send(file_notif, SendSessions::EveryoneExcept(session)) - .await?; + info.send(file_notif, SendSessions::EveryoneExcept(session))?; Ok(None) } @@ -110,7 +108,7 @@ impl traits::Service for Presence { let mut files = vec![]; for file in self.files.values() { - files.push(file.clone()) + files.push(file.clone()); } _inner.files = files; @@ -129,8 +127,7 @@ impl traits::Service for Presence { ..Default::default() }; - info.send(join, SendSessions::EveryoneExcept(session)) - .await?; + info.send(join, SendSessions::EveryoneExcept(session))?; self.users.push(user); @@ -149,8 +146,7 @@ impl traits::Service for Presence { trace!(%session, "Sending depart notification"); - info.send(part, SendSessions::EveryoneExcept(session)) - .await?; + info.send(part, SendSessions::EveryoneExcept(session))?; debug!(?user, "Sent depart notification"); diff --git a/services/src/shell.rs b/services/src/shell.rs index 24c5760..2e2c873 100644 --- a/services/src/shell.rs +++ b/services/src/shell.rs @@ -47,10 +47,10 @@ impl traits::Service for Shell { match body { goval::command::Body::Input(msg) => { - self.pty.write(msg)?; + self.pty.write(&msg)?; } goval::command::Body::ResizeTerm(size) => { - self.pty.resize(size.rows as u16, size.cols as u16)? + self.pty.resize(size.rows as u16, size.cols as u16)?; } _ => { debug!(?message, "New message"); @@ -64,7 +64,7 @@ impl traits::Service for Shell { info: &super::types::ChannelInfo, _exit_code: i32, ) -> Result<()> { - self.pty = Shell::start_pty(info).await?; + self.pty = Shell::start_pty(info)?; Ok(()) } } @@ -75,7 +75,7 @@ static DEFAULT_SHELL: &str = "sh"; static DEFAULT_SHELL: &str = "pwsh"; impl Shell { - async fn start_pty(info: &super::types::ChannelInfo) -> Result { + fn start_pty(info: &super::types::ChannelInfo) -> Result { let mut env = HashMap::new(); env.insert("REPLIT_GIT_TOOLS_CHANNEL_FROM".into(), info.id.to_string()); @@ -83,14 +83,14 @@ impl Shell { vec![std::env::var("SHELL").unwrap_or(DEFAULT_SHELL.to_string())], info.id, Arc::new(RwLock::new(info.clients.clone())), - info.sender.clone(), + &info.sender, Some(env), ) - .await } - pub async fn new(info: &super::types::ChannelInfo) -> Result { + + pub fn new(info: &super::types::ChannelInfo) -> Result { Ok(Shell { - pty: Shell::start_pty(info).await?, + pty: Shell::start_pty(info)?, }) } } diff --git a/services/src/types/channel_info.rs b/services/src/types/channel_info.rs index cb9bcf8..f49b59f 100644 --- a/services/src/types/channel_info.rs +++ b/services/src/types/channel_info.rs @@ -30,33 +30,33 @@ pub struct ChannelInfo { } impl ChannelInfo { - pub async fn send(&self, mut message: goval::Command, sessions: SendSessions) -> Result<()> { + pub fn send(&self, mut message: goval::Command, sessions: SendSessions) -> Result<()> { let clients: Vec; message.channel = self.id.into(); match sessions { SendSessions::Everyone => { message.session = 0; - let mut _clients = vec![]; + let mut all_clients = vec![]; for client in self.clients.keys() { - _clients.push(*client) + all_clients.push(*client); } - clients = _clients; + clients = all_clients; } SendSessions::EveryoneExcept(excluded) => { message.session = (-excluded).into(); - let mut _clients = vec![]; + let mut most_client = vec![]; for client in self.clients.keys() { if client != &excluded { - _clients.push(*client) + most_client.push(*client); } } - clients = _clients; + clients = most_client; } SendSessions::Only(session) => { message.session = session.into(); - clients = vec![session] + clients = vec![session]; } } @@ -67,7 +67,7 @@ impl ChannelInfo { session: client, })?; } else { - error!("Missing session outbound message queue in op_send_msg") + error!("Missing session outbound message queue in op_send_msg"); } } Ok(()) diff --git a/services/src/types/client.rs b/services/src/types/client.rs index bc71a2b..bc7494a 100644 --- a/services/src/types/client.rs +++ b/services/src/types/client.rs @@ -12,7 +12,7 @@ impl Default for ClientInfo { is_secure: false, username: "homeval-user".to_owned(), - id: 23054564, + id: 23_054_564, } } } diff --git a/services/src/types/config.rs b/services/src/types/config.rs index e5daae6..df3f823 100644 --- a/services/src/types/config.rs +++ b/services/src/types/config.rs @@ -1,3 +1,5 @@ +#![allow(clippy::wildcard_imports)] + /* message ToolchainConfigs { string entrypoint = 1; @@ -168,11 +170,11 @@ pub mod dotreplit { if let Some(languages) = &val.languages { let mut inner = HashMap::new(); - for (lang, data) in languages.iter() { + for (lang, data) in languages { inner.insert(lang.into(), data.into()); } - ret.languages = inner + ret.languages = inner; } if let Some(hidden) = &val.hidden { diff --git a/services/src/types/fs_watcher.rs b/services/src/types/fs_watcher.rs index 5cb62d8..1d228ab 100644 --- a/services/src/types/fs_watcher.rs +++ b/services/src/types/fs_watcher.rs @@ -6,7 +6,7 @@ use notify_debouncer_full::{ use serde::Serialize; use tracing::error; -use anyhow::Result; +use anyhow::{format_err, Result}; use std::{path::Path, time::Duration}; @@ -54,7 +54,9 @@ impl FSWatcher { None, move |result: DebounceEventResult| match result { Ok(events) => events.iter().for_each(|event| { - if let Some(final_event) = notify_event_to_final(event).unwrap() { + if let Some(final_event) = + notify_event_to_final(event).expect("TODO: handle this") + { debounce_writer .send(ChannelMessage::FSEvent(final_event)) .expect("TODO: handle this"); @@ -78,7 +80,7 @@ impl FSWatcher { Ok(FSWatcher { debouncer, writer }) } - pub async fn watch(&mut self, files: Vec) -> Result<()> { + pub fn watch(&mut self, files: Vec) -> Result<()> { for file in files { let path = Path::new(&file); self.debouncer @@ -86,42 +88,50 @@ impl FSWatcher { .watch(path, notify::RecursiveMode::NonRecursive)?; self.debouncer .cache() - .add_root(path, notify::RecursiveMode::NonRecursive) + .add_root(path, notify::RecursiveMode::NonRecursive); } Ok(()) } - pub async fn shutdown(self) { + pub fn shutdown(self) { self.debouncer.stop_nonblocking(); - drop(self.writer) + drop(self.writer); } } fn notify_event_to_final(event: &Event) -> Result> { let base = std::env::current_dir()?; - let file_name = event.paths[0] + let Some(file_name) = event.paths[0] .strip_prefix(base.clone())? .to_str() - .unwrap() - .to_string(); + .map(String::from) + else { + return Err(format_err!( + "Got invalid utf-8 when trying to find FSEvent file name :eyes:" + )); + }; + match event.kind { EventKind::Create(_) => Ok(Some(FSEvent::Create(file_name))), EventKind::Modify(_kind @ ModifyKind::Name(notify::event::RenameMode::Both)) => { - Ok(Some(FSEvent::Rename( - file_name, - event.paths[1] - .strip_prefix(base)? - .to_str() - .unwrap() - .to_string(), - ))) + let Some(resultant) = event.paths[1] + .strip_prefix(base.clone())? + .to_str() + .map(String::from) + else { + return Err(format_err!( + "Got invalid utf-8 when trying to find FSEvent resultant file name :eyes:" + )); + }; + + Ok(Some(FSEvent::Rename(file_name, resultant))) } EventKind::Modify(_kind @ ModifyKind::Name(notify::event::RenameMode::From)) => { - Ok(Some(FSEvent::Remove(file_name.to_string()))) + Ok(Some(FSEvent::Remove(file_name))) } EventKind::Modify(_kind @ ModifyKind::Name(notify::event::RenameMode::To)) => { - Ok(Some(FSEvent::Create(file_name.to_string()))) + Ok(Some(FSEvent::Create(file_name))) } EventKind::Modify(_) => Ok(Some(FSEvent::Modify(file_name))), EventKind::Remove(_) => Ok(Some(FSEvent::Remove(file_name))), diff --git a/services/src/types/proc.rs b/services/src/types/proc.rs index 2aaaee1..f65fe75 100644 --- a/services/src/types/proc.rs +++ b/services/src/types/proc.rs @@ -86,19 +86,19 @@ pub struct Proc { } impl Proc { - pub async fn new( - _args: Vec, + pub fn new( + args: Vec, channel: ChannelID, contact: tokio::sync::mpsc::UnboundedSender, - _env: Option>, + _env: Option<&HashMap>, ) -> Result { let cancelled = Arc::new(AtomicBool::new(false)); - let mut cmd = tokio::process::Command::new(&_args[0]); - let args = &mut VecDeque::from(_args.to_vec()); - trace!("{:#?}", args); - VecDeque::pop_front(args); - for arg in args { + let mut cmd = tokio::process::Command::new(&args[0]); + let real_args = &mut VecDeque::from(args); + trace!("{:#?}", real_args); + VecDeque::pop_front(real_args); + for arg in real_args { cmd.arg(arg); } // debug!("{:#?}", std::env::current_dir()?); @@ -167,7 +167,7 @@ impl Proc { .send(ChannelMessage::ProcessDead(exit_status)) .is_err() { - error!("Proc recv'ing channel was dropped before process dead alert was sent") + error!("Proc recv'ing channel was dropped before process dead alert was sent"); } }); diff --git a/services/src/types/pty.rs b/services/src/types/pty.rs index 4891d94..fb83efa 100644 --- a/services/src/types/pty.rs +++ b/services/src/types/pty.rs @@ -73,7 +73,7 @@ impl Write for PtyWriter { command: to_send, session: *session, }) { - Ok(_) => {} + Ok(()) => {} Err(err) => { return Err(Error::new(ErrorKind::Other, err)); } @@ -99,14 +99,14 @@ pub struct Pty { } impl Pty { - pub async fn start( - _args: Vec, + pub fn start( + args: Vec, channel: ChannelID, sessions: Arc>>>, - contact: tokio::sync::mpsc::UnboundedSender, - _env: Option>, + contact: &tokio::sync::mpsc::UnboundedSender, + env: Option>, ) -> Result { - let env = _env.unwrap_or_default(); + let env = env.unwrap_or_default(); let pty_system = portable_pty::native_pty_system(); @@ -117,16 +117,16 @@ impl Pty { ..Default::default() })?; - let mut cmd = portable_pty::CommandBuilder::new(_args[0].clone()); - let args = &mut VecDeque::from(_args.to_vec()); - VecDeque::pop_front(args); - for arg in args { + let mut cmd = portable_pty::CommandBuilder::new(args[0].clone()); + let real_args = &mut VecDeque::from(args); + VecDeque::pop_front(real_args); + for arg in real_args { cmd.arg(arg); } cmd.cwd(std::env::current_dir()?); - for (key, val) in env.into_iter() { - cmd.env(key, val) + for (key, val) in env { + cmd.env(key, val); } let child = pair.slave.spawn_command(cmd)?; @@ -187,19 +187,19 @@ impl Pty { // let queue = _read.get(&channel).unwrap().clone(); // drop(_read); match contact_clone.send(ChannelMessage::ProcessDead(exit_code)) { - Ok(_) => {} + Ok(()) => {} Err(err) => { - error!(%err, "PTY child proc reaper errored when alerting channel") + error!(%err, "PTY child proc reaper errored when alerting channel"); } } } Err(err) => { - error!(%err, "PTY child proc reaper errored") + error!(%err, "PTY child proc reaper errored"); } } } Err(err) => { - error!(%err, "Join error on pty child proc reaper") + error!(%err, "Join error on pty child proc reaper"); } } }); @@ -252,7 +252,7 @@ impl Pty { Ok(()) } - pub fn write(&mut self, task: String) -> Result<()> { + pub fn write(&mut self, task: &str) -> Result<()> { if self.cancelled.load(std::sync::atomic::Ordering::SeqCst) { return Err(format_err!("Can't write to a cancelled pty")); } From 694dd094bcddf6b66568252f122f1b5f64a201e6 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:42:51 -0700 Subject: [PATCH 097/103] refactor(services, server): Enable more clippy lints - Warn for useless `clone()` calls - Warn for functions that could be marked `const` but are not. --- services/src/chat.rs | 2 +- services/src/lib.rs | 7 ++++++- services/src/output.rs | 2 +- services/src/snapshot.rs | 2 +- services/src/types/fs_watcher.rs | 2 +- services/src/types/messaging.rs | 2 +- src/main.rs | 6 +++++- 7 files changed, 16 insertions(+), 7 deletions(-) diff --git a/services/src/chat.rs b/services/src/chat.rs index 987f457..a6c75a6 100644 --- a/services/src/chat.rs +++ b/services/src/chat.rs @@ -10,7 +10,7 @@ use async_trait::async_trait; use tracing::warn; impl Chat { - pub fn new() -> Chat { + pub const fn new() -> Chat { Chat { history: vec![] } } } diff --git a/services/src/lib.rs b/services/src/lib.rs index 78f4bbe..04e7736 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -1,5 +1,10 @@ #![feature(extract_if)] -#![warn(clippy::pedantic, clippy::unwrap_used)] +#![warn( + clippy::pedantic, + clippy::unwrap_used, + clippy::redundant_clone, + clippy::missing_const_for_fn +)] #![allow( clippy::module_name_repetitions, clippy::must_use_candidate, diff --git a/services/src/output.rs b/services/src/output.rs index dc215f2..4bce5e2 100644 --- a/services/src/output.rs +++ b/services/src/output.rs @@ -191,7 +191,7 @@ impl traits::Service for Output { } impl Output { - pub fn new() -> Output { + pub const fn new() -> Output { Output { pty: None, start_time: None, diff --git a/services/src/snapshot.rs b/services/src/snapshot.rs index a0a7779..4dcadc5 100644 --- a/services/src/snapshot.rs +++ b/services/src/snapshot.rs @@ -14,7 +14,7 @@ impl traits::Service for Snapshot { message: goval::Command, _session: SessionID, ) -> Result> { - let body = match message.body.clone() { + let body = match message.body { None => return Err(format_err!("Expected command body")), Some(body) => body, }; diff --git a/services/src/types/fs_watcher.rs b/services/src/types/fs_watcher.rs index 1d228ab..ff16431 100644 --- a/services/src/types/fs_watcher.rs +++ b/services/src/types/fs_watcher.rs @@ -116,7 +116,7 @@ fn notify_event_to_final(event: &Event) -> Result> { EventKind::Create(_) => Ok(Some(FSEvent::Create(file_name))), EventKind::Modify(_kind @ ModifyKind::Name(notify::event::RenameMode::Both)) => { let Some(resultant) = event.paths[1] - .strip_prefix(base.clone())? + .strip_prefix(base)? .to_str() .map(String::from) else { diff --git a/services/src/types/messaging.rs b/services/src/types/messaging.rs index d6bd91e..3388f43 100644 --- a/services/src/types/messaging.rs +++ b/services/src/types/messaging.rs @@ -45,7 +45,7 @@ pub struct IPCMessage { } impl IPCMessage { - pub fn replace_cmd(&self, cmd: goval::Command) -> IPCMessage { + pub const fn replace_cmd(&self, cmd: goval::Command) -> IPCMessage { IPCMessage { command: cmd, session: self.session, diff --git a/src/main.rs b/src/main.rs index 30c7c96..898e03b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,9 @@ #![feature(lazy_cell)] -#![warn(clippy::pedantic)] +#![warn( + clippy::pedantic, + clippy::redundant_clone, + clippy::missing_const_for_fn +)] use std::sync::LazyLock; use std::time::Instant; From 884f7f4d5022036c9baec6c3eab4ed0abc228395 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 27 Apr 2024 12:54:35 -0700 Subject: [PATCH 098/103] refactor(server): Remove most uses of `.unwrap()` --- services/src/types/config.rs | 2 +- src/database.rs | 4 +++- src/goval_server.rs | 11 ++++++++++- src/main.rs | 12 +++++++----- src/parse_paseto.rs | 2 +- src/replspace_server.rs | 8 ++------ 6 files changed, 24 insertions(+), 15 deletions(-) diff --git a/services/src/types/config.rs b/services/src/types/config.rs index df3f823..372417a 100644 --- a/services/src/types/config.rs +++ b/services/src/types/config.rs @@ -139,7 +139,7 @@ pub mod dotreplit { map languages = 9; repeated string hidden = 11; */ - #[derive(Serialize, Deserialize, Debug)] + #[derive(Serialize, Deserialize, Debug, Default)] #[serde(rename_all = "camelCase")] pub struct DotReplit { pub run: Option, diff --git a/src/database.rs b/src/database.rs index c0fa3ac..60f3824 100644 --- a/src/database.rs +++ b/src/database.rs @@ -35,7 +35,9 @@ pub async fn setup() -> Result<()> { migration::Migrator::up(&db, None).await?; debug!("Setting database once cell"); - DATABASE.set(db).unwrap(); + DATABASE + .set(db) + .expect("This function is the only possible call to DATABASE.set and is only called once"); debug!("Done with database setup"); diff --git a/src/goval_server.rs b/src/goval_server.rs index f063dc6..2b23ddc 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -1,3 +1,6 @@ +// TODO: Fix all these warnings and remove this allow +#![allow(clippy::unwrap_used)] + use axum::{ extract::{ ws::{Message as WsMessage, WebSocket, WebSocketUpgrade}, @@ -182,7 +185,13 @@ async fn handle_message(message: IPCMessage, max_channel: &Mutex) { let msg_lock = CHANNEL_MESSAGES.read().await; let channel_id = ChannelID(cmd.channel); - let queue = msg_lock.get(&channel_id).unwrap().clone(); + let Some(queue) = msg_lock.get(&channel_id).cloned() else { + error!( + "Session {} sent message to unknown channel {channel_id}", + message.session + ); + return; + }; drop(msg_lock); diff --git a/src/main.rs b/src/main.rs index 898e03b..2842b75 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,15 @@ #![feature(lazy_cell)] #![warn( clippy::pedantic, + clippy::unwrap_used, clippy::redundant_clone, clippy::missing_const_for_fn )] +use anyhow::Result; use std::sync::LazyLock; use std::time::Instant; -use std::{collections::HashMap, io::Error, sync::Arc}; +use std::{collections::HashMap, sync::Arc}; use homeval_services::{ChannelID, SessionID}; use tokio::sync::RwLock; @@ -35,7 +37,7 @@ static CPU_STATS: LazyLock> = pub static DOTREPLIT_CONFIG: LazyLock>> = LazyLock::new(|| { Arc::new(RwLock::const_new( - toml::from_str(&std::fs::read_to_string(".replit").unwrap_or_default()).unwrap(), + toml::from_str(&std::fs::read_to_string(".replit").unwrap_or_default()).unwrap_or_default(), )) }); @@ -61,7 +63,7 @@ pub use database::DATABASE; mod goval_server; #[tokio::main] -async fn main() -> Result<(), Error> { +async fn main() -> Result<()> { tracing_subscriber::fmt::init(); debug!("Initializing lazy statics"); LazyLock::force(&START_TIME); @@ -74,7 +76,7 @@ async fn main() -> Result<(), Error> { // console_subscriber::init(); #[cfg(feature = "database")] - database::setup().await.unwrap(); + database::setup().await?; info!("Starting homeval!"); @@ -84,7 +86,7 @@ async fn main() -> Result<(), Error> { #[cfg(feature = "repldb")] tokio::spawn(repldb_server::start_server()); - goval_server::start_server().await.unwrap(); + goval_server::start_server().await?; Ok(()) } diff --git a/src/parse_paseto.rs b/src/parse_paseto.rs index 360a45b..9555624 100644 --- a/src/parse_paseto.rs +++ b/src/parse_paseto.rs @@ -101,7 +101,7 @@ async fn parse_verify(input: &str) -> Result<(Vec, bool)> { pubkey = pasetors::keys::AsymmetricPublicKey::from( general_purpose::STANDARD.decode(key)?.as_slice(), ) - .unwrap(); + .expect("Invalid signing key"); } else { return Err(Error::new( std::io::ErrorKind::InvalidData, diff --git a/src/replspace_server.rs b/src/replspace_server.rs index a547694..c27fc6a 100644 --- a/src/replspace_server.rs +++ b/src/replspace_server.rs @@ -21,12 +21,8 @@ pub async fn start_server() -> Result<()> { .route("/files/open", post(open_file)) .route("/github/token", get(get_gh_token)); - let listener = tokio::net::TcpListener::bind(&"127.0.0.1:8283".parse::()?) - .await - .unwrap(); - axum::serve(listener, app.into_make_service()) - .await - .unwrap(); + let listener = tokio::net::TcpListener::bind(&"127.0.0.1:8283".parse::()?).await?; + axum::serve(listener, app.into_make_service()).await?; Ok(()) } From 6ccd4ef204defe3861564b0f67ed556dff43af51 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 27 Apr 2024 13:06:41 -0700 Subject: [PATCH 099/103] build: Update Cargo.lock --- Cargo.lock | 751 ++++++++++++++++++++++++++--------------------------- 1 file changed, 366 insertions(+), 385 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73b63e9..e1b9bc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,23 +19,23 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "ahash" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.14", "once_cell", "version_check", ] [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom 0.2.12", + "getrandom 0.2.14", "once_cell", "version_check", "zerocopy", @@ -43,9 +43,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -58,9 +58,9 @@ checksum = "250f629c0161ad8107cf89319e990051fae62832fd343083bea452d93e2205fd" [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "android-tzdata" @@ -79,9 +79,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" dependencies = [ "anstyle", "anstyle-parse", @@ -93,9 +93,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" @@ -127,9 +127,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" [[package]] name = "arrayvec" @@ -156,7 +156,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -167,7 +167,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -179,21 +179,11 @@ dependencies = [ "num-traits", ] -[[package]] -name = "atomic-write-file" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" -dependencies = [ - "nix 0.27.1", - "rand 0.8.5", -] - [[package]] name = "autocfg" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" [[package]] name = "axum" @@ -255,9 +245,9 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ "addr2line", "cc", @@ -305,9 +295,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" dependencies = [ "serde", ] @@ -335,9 +325,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667" +checksum = "0901fc8eb0aca4c83be0106d6f2db17d86a08dfc2c25f0e84464bf381158add6" dependencies = [ "borsh-derive", "cfg_aliases", @@ -345,29 +335,29 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd" +checksum = "51670c3aa053938b0ee3bd67c3817e471e626151131b934038e83c5bf8de48f5" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", "syn_derive", ] [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytecheck" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" dependencies = [ "bytecheck_derive", "ptr_meta", @@ -376,9 +366,9 @@ dependencies = [ [[package]] name = "bytecheck_derive" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" dependencies = [ "proc-macro2", "quote", @@ -393,18 +383,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" -version = "1.0.83" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] +checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" [[package]] name = "cfg-if" @@ -428,7 +415,7 @@ dependencies = [ "iana-time-zone", "num-traits", "serde", - "windows-targets 0.52.0", + "windows-targets 0.52.5", ] [[package]] @@ -455,9 +442,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.18" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", "clap_derive", @@ -465,9 +452,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.18" +version = "4.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", @@ -477,21 +464,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.7" +version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "clap_lex" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" [[package]] name = "colorchoice" @@ -542,9 +529,9 @@ dependencies = [ [[package]] name = "crc" -version = "3.0.1" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" dependencies = [ "crc-catalog", ] @@ -566,9 +553,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" dependencies = [ "crossbeam-utils", ] @@ -622,9 +609,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "pem-rfc7468", @@ -672,24 +659,24 @@ checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" [[package]] name = "downcast-rs" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "ed25519-compact" -version = "2.0.6" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a667e6426df16c2ac478efa4a439d0e674cba769c5556e8cf221739251640c8c" +checksum = "e9b3460f44bea8cd47f45a0c70892f1eff856d97cd55358b2f73f663789f6190" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.14", ] [[package]] name = "either" -version = "1.9.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" dependencies = [ "serde", ] @@ -737,15 +724,15 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fastrand" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" [[package]] name = "fiat-crypto" -version = "0.2.5" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" +checksum = "38793c55593b33412e3ae40c2c9781ffaa6f438f6f8c10f24e71846fbd7ae01e" [[package]] name = "file-id" @@ -775,7 +762,7 @@ checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.4.1", "windows-sys 0.52.0", ] @@ -914,7 +901,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -970,9 +957,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" dependencies = [ "cfg-if", "js-sys", @@ -1018,7 +1005,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash 0.7.7", + "ahash 0.7.8", ] [[package]] @@ -1027,7 +1014,7 @@ version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ - "ahash 0.8.7", + "ahash 0.8.11", "allocator-api2", ] @@ -1049,11 +1036,17 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1127,9 +1120,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1148,12 +1141,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ "bytes", - "futures-util", + "futures-core", "http", "http-body", "pin-project-lite", @@ -1173,9 +1166,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.1.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75" +checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" dependencies = [ "bytes", "futures-channel", @@ -1187,6 +1180,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", + "smallvec", "tokio", "want", ] @@ -1229,9 +1223,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1262,9 +1256,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -1278,7 +1272,7 @@ checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -1312,33 +1306,24 @@ dependencies = [ [[package]] name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -1374,9 +1359,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.152" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libm" @@ -1397,15 +1382,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1413,9 +1398,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" [[package]] name = "matchers" @@ -1444,9 +1429,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" [[package]] name = "memoffset" @@ -1479,9 +1464,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", ] @@ -1500,9 +1485,9 @@ dependencies = [ [[package]] name = "multimap" -version = "0.8.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" [[package]] name = "native-tls" @@ -1536,17 +1521,6 @@ dependencies = [ "pin-utils", ] -[[package]] -name = "nix" -version = "0.27.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags 2.4.1", - "cfg-if", - "libc", -] - [[package]] name = "nom" version = "7.1.3" @@ -1563,7 +1537,7 @@ version = "6.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.5.0", "crossbeam-channel", "filetime", "fsevent-sys", @@ -1627,21 +1601,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" dependencies = [ "autocfg", "num-integer", @@ -1650,9 +1629,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", "libm", @@ -1685,11 +1664,11 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "openssl" -version = "0.10.62" +version = "0.10.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.5.0", "cfg-if", "foreign-types", "libc", @@ -1706,7 +1685,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -1717,9 +1696,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.98" +version = "0.9.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" dependencies = [ "cc", "libc", @@ -1764,11 +1743,11 @@ version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec4c6225c69b4ca778c0aea097321a64c421cf4577b331c61b229267edabb6f8" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -1779,9 +1758,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" dependencies = [ "lock_api", "parking_lot_core", @@ -1789,15 +1768,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.1", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.5", ] [[package]] @@ -1817,7 +1796,7 @@ checksum = "6b36d47c66f2230dd1b7143d9afb2b4891879020210eddf2ccb624e529b96dba" dependencies = [ "ct-codecs", "ed25519-compact", - "getrandom 0.2.12", + "getrandom 0.2.14", "orion", "subtle", "zeroize", @@ -1894,29 +1873,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -1947,9 +1926,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "portable-pty" @@ -1964,7 +1943,7 @@ dependencies = [ "lazy_static", "libc", "log", - "nix 0.25.1", + "nix", "serial", "shared_library", "shell-words", @@ -1986,21 +1965,21 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "prettyplease" -version = "0.2.16" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +checksum = "5ac2cf0f2e4f42b49f5ffd07dae8d746508ef7526c13940e5f524012ae6c6550" dependencies = [ "proc-macro2", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "proc-macro-crate" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b2685dd208a3771337d8d386a89840f0f43cd68be8dae90a5f8c2384effc9cd" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit 0.21.0", + "toml_edit 0.21.1", ] [[package]] @@ -2029,9 +2008,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" dependencies = [ "unicode-ident", ] @@ -2048,13 +2027,13 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" +checksum = "80b776a1b2dc779f5ee0641f8ade0125bc1298dd41a9a0c16d8bd57b42d222b1" dependencies = [ "bytes", - "heck", - "itertools 0.10.5", + "heck 0.5.0", + "itertools", "log", "multimap", "once_cell", @@ -2063,9 +2042,8 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.48", + "syn 2.0.60", "tempfile", - "which", ] [[package]] @@ -2075,17 +2053,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" dependencies = [ "anyhow", - "itertools 0.12.0", + "itertools", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "prost-types" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +checksum = "3235c33eb02c1f1e212abdbe34c78b264b038fb58ca612664343271e36e55ffe" dependencies = [ "prost", ] @@ -2121,9 +2099,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ "proc-macro2", ] @@ -2193,7 +2171,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.12", + "getrandom 0.2.14", ] [[package]] @@ -2214,16 +2192,25 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + [[package]] name = "regex" -version = "1.10.2" +version = "1.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", - "regex-syntax 0.8.2", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", ] [[package]] @@ -2237,13 +2224,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.3", ] [[package]] @@ -2254,38 +2241,39 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" [[package]] name = "rend" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" dependencies = [ "bytecheck", ] [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", - "getrandom 0.2.12", + "cfg-if", + "getrandom 0.2.14", "libc", "spin 0.9.8", "untrusted", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rkyv" -version = "0.7.43" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527a97cdfef66f65998b5f3b637c26f5a5ec09cc52a3f9932313ac645f4190f5" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" dependencies = [ "bitvec", "bytecheck", @@ -2301,9 +2289,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.43" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5c462a1328c8e67e4d6dbad1eb0355dd43e8ab432c6e227a43657f16ade5033" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" dependencies = [ "proc-macro2", "quote", @@ -2342,9 +2330,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.33.1" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06676aec5ccb8fc1da723cc8c0f9a46549f21ebb8753d3915c6c41db1e7f1dc4" +checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" dependencies = [ "arrayvec", "borsh", @@ -2364,11 +2352,11 @@ checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", @@ -2377,9 +2365,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.11" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "ring", "rustls-webpki", @@ -2407,15 +2395,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" [[package]] name = "same-file" @@ -2457,18 +2445,18 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bd3534a9978d0aa7edd2808dc1f8f31c4d0ecd31ddf71d997b3c98e9f3c9114" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "sea-orm" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6632f499b80cc6aaa781b302e4c9fae663e0e3dcf2640e9d80034d5b10731efe" +checksum = "c8814e37dc25de54398ee62228323657520b7f29713b8e238649385dbe473ee0" dependencies = [ "async-stream", "async-trait", @@ -2494,9 +2482,9 @@ dependencies = [ [[package]] name = "sea-orm-cli" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "465ea2308d4716837e9af4a2cff8e14c28135867a580bb93e9e03d408a3a6afb" +checksum = "620bc560062ae251b1366bde43b3f1508445cab5c2c8cbdb397034638ab1b357" dependencies = [ "chrono", "clap", @@ -2511,23 +2499,23 @@ dependencies = [ [[package]] name = "sea-orm-macros" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec13bfb4c4aef208f68dbea970dd40d13830c868aa8dcb4e106b956e6bb4f2fa" +checksum = "5e115c6b078e013aa963cc2d38c196c2c40b05f03d0ac872fe06b6e0d5265603" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "sea-bae", - "syn 2.0.48", + "syn 2.0.60", "unicode-ident", ] [[package]] name = "sea-orm-migration" -version = "0.12.14" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac734b6e5610c2764056cc8495fbc293cd1c8ebe084fdfb74c3b0cdaaff9bb92" +checksum = "ee8269bc6ff71afd6b78aa4333ac237a69eebd2cdb439036291e64fb4b8db23c" dependencies = [ "async-trait", "clap", @@ -2580,10 +2568,10 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25a82fcb49253abcb45cdcb2adf92956060ec0928635eb21b4f7a6d8f25ab0bc" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", "thiserror", ] @@ -2604,7 +2592,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6f686050f76bffc4f635cda8aea6df5548666b830b52387e8bc7de11056d11e" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "syn 1.0.109", @@ -2618,9 +2606,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "security-framework" -version = "2.9.2" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -2631,9 +2619,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" dependencies = [ "core-foundation-sys", "libc", @@ -2641,29 +2629,29 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.197" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "0c9f6e76df036c77cd94996771fb40db98187f096dd0b9af39c6c6e452ba966a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.199" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "serde_json" -version = "1.0.115" +version = "1.0.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" dependencies = [ "itoa", "ryu", @@ -2672,9 +2660,9 @@ dependencies = [ [[package]] name = "serde_path_to_error" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" dependencies = [ "itoa", "serde", @@ -2815,9 +2803,9 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -2840,9 +2828,9 @@ checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" [[package]] name = "similar" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32fea41aca09ee824cc9724996433064c89f7777e60762749a4170a14abbfa21" +checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" [[package]] name = "siphasher" @@ -2861,18 +2849,18 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2906,16 +2894,16 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" dependencies = [ - "itertools 0.12.0", + "itertools", "nom", "unicode_categories", ] [[package]] name = "sqlx" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" +checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" dependencies = [ "sqlx-core", "sqlx-macros", @@ -2926,11 +2914,11 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" +checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" dependencies = [ - "ahash 0.8.7", + "ahash 0.8.11", "atoi", "bigdecimal", "byteorder", @@ -2938,7 +2926,6 @@ dependencies = [ "chrono", "crc", "crossbeam-queue", - "dotenvy", "either", "event-listener", "futures-channel", @@ -2974,9 +2961,9 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" dependencies = [ "proc-macro2", "quote", @@ -2987,14 +2974,13 @@ dependencies = [ [[package]] name = "sqlx-macros-core" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" +checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" dependencies = [ - "atomic-write-file", "dotenvy", "either", - "heck", + "heck 0.4.1", "hex", "once_cell", "proc-macro2", @@ -3014,14 +3000,14 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" +checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" dependencies = [ "atoi", "base64 0.21.7", "bigdecimal", - "bitflags 2.4.1", + "bitflags 2.5.0", "byteorder", "bytes", "chrono", @@ -3061,14 +3047,14 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" +checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" dependencies = [ "atoi", "base64 0.21.7", "bigdecimal", - "bitflags 2.4.1", + "bitflags 2.5.0", "byteorder", "chrono", "crc", @@ -3092,7 +3078,6 @@ dependencies = [ "rust_decimal", "serde", "serde_json", - "sha1", "sha2", "smallvec", "sqlx-core", @@ -3106,9 +3091,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" +checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" dependencies = [ "atoi", "chrono", @@ -3155,9 +3140,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "strum" @@ -3184,9 +3169,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" dependencies = [ "proc-macro2", "quote", @@ -3202,7 +3187,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -3225,13 +3210,12 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.9.0" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", "rustix", "windows-sys 0.52.0", ] @@ -3257,29 +3241,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ "cfg-if", "once_cell", @@ -3287,12 +3271,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -3307,10 +3292,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -3331,9 +3317,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" dependencies = [ "backtrace", "bytes", @@ -3356,7 +3342,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -3371,9 +3357,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" dependencies = [ "futures-core", "pin-project-lite", @@ -3415,7 +3401,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.9", + "toml_edit 0.22.12", ] [[package]] @@ -3429,26 +3415,26 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ "indexmap", "toml_datetime", - "winnow 0.5.34", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.22.9" +version = "0.22.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" +checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.1", + "winnow 0.6.7", ] [[package]] @@ -3499,7 +3485,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] @@ -3584,9 +3570,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -3596,18 +3582,18 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode_categories" @@ -3652,9 +3638,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.6.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ "serde", ] @@ -3679,9 +3665,9 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -3716,9 +3702,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3726,24 +3712,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3751,40 +3737,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "whoami" @@ -3792,7 +3766,7 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" dependencies = [ - "redox_syscall", + "redox_syscall 0.4.1", "wasite", ] @@ -3814,11 +3788,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" dependencies = [ - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -3833,7 +3807,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.5", ] [[package]] @@ -3851,7 +3825,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.5", ] [[package]] @@ -3871,17 +3845,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] @@ -3892,9 +3867,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" [[package]] name = "windows_aarch64_msvc" @@ -3904,9 +3879,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" [[package]] name = "windows_i686_gnu" @@ -3916,9 +3891,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" [[package]] name = "windows_i686_msvc" @@ -3928,9 +3909,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" [[package]] name = "windows_x86_64_gnu" @@ -3940,9 +3921,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" [[package]] name = "windows_x86_64_gnullvm" @@ -3952,9 +3933,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" [[package]] name = "windows_x86_64_msvc" @@ -3964,24 +3945,24 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] name = "winnow" -version = "0.5.34" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] [[package]] name = "winnow" -version = "0.6.1" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d90f4e0f530c4c69f62b80d839e9ef3855edc9cba471a160c4d692deed62b401" +checksum = "14b9415ee827af173ebb3f15f9083df5a122eb93572ec28741fb153356ea2578" dependencies = [ "memchr", ] @@ -4021,7 +4002,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.60", ] [[package]] From 35ce3ad7719cf8d21b8ed2d446d2495887633899 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 27 Apr 2024 17:08:48 -0700 Subject: [PATCH 100/103] feat(services, goval-ident): Implement chat variant of `goval-ident` protocol - Fully implements [`goval-ident`](https://govaldocs.pages.dev/service/goval-ident/) - Makes `goval-ident` a disable-able feature - Unifies implemention of `chat` and `gcsfiles` variants --- Cargo.toml | 3 +- services/Cargo.toml | 6 +- services/src/gcsfiles.rs | 18 ++-- services/src/goval_ident.rs | 131 +++++++++++++++++++++++++++++ services/src/lib.rs | 26 +++++- services/src/types/channel_info.rs | 4 +- services/src/types/fs_watcher.rs | 4 +- services/src/types/messaging.rs | 4 +- services/src/types/mod.rs | 3 + services/src/types/server_info.rs | 46 ++++++++++ src/goval_server.rs | 5 +- src/main.rs | 7 +- src/server_info.rs | 16 ++++ 13 files changed, 245 insertions(+), 28 deletions(-) create mode 100644 services/src/goval_ident.rs create mode 100644 services/src/types/server_info.rs create mode 100644 src/server_info.rs diff --git a/Cargo.toml b/Cargo.toml index d5fe515..0b2b06d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,12 +17,13 @@ See https://govaldocs.pages.dev""" members = [".", "migration", "entity", "services", "protobuf"] [features] -default = ["replspace", "database", "repldb", "verify_connections"] +default = ["replspace", "database", "repldb", "verify_connections", "goval-ident"] repldb = ["database"] database = ["dep:sea-orm", "dep:sea-query", "dep:migration", "dep:entity"] replspace = [] fun-stuff = ["dep:chrono", "dep:chrono-tz"] verify_connections = ["dep:hyper", "dep:hyper-tls", "dep:hyper-util", "dep:http-body-util"] +goval-ident = ["homeval_services/goval-ident"] [dependencies] goval = { path = "protobuf", package = "protobuf" } diff --git a/services/Cargo.toml b/services/Cargo.toml index c220aa4..f3f78cb 100644 --- a/services/Cargo.toml +++ b/services/Cargo.toml @@ -4,6 +4,8 @@ version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +goval-ident = ["dep:serde_json"] [dependencies] anyhow = "1.0.81" @@ -18,12 +20,14 @@ prost = "0.12.4" prost-types = "0.12.3" ropey = "1.6.0" serde = "1.0.197" -serde_json = "1.0.115" similar = "2.2.1" tokio = "1.36.0" tracing = "0.1.40" tracing-futures = "0.2.5" +# goval-ident features +serde_json = { version = "1.0.116", optional = true } + [lib] name = "services" path = "src/lib.rs" diff --git a/services/src/gcsfiles.rs b/services/src/gcsfiles.rs index 6d8b3a8..7688fb2 100644 --- a/services/src/gcsfiles.rs +++ b/services/src/gcsfiles.rs @@ -12,7 +12,7 @@ use tracing::{debug, warn}; impl traits::Service for GCSFiles { async fn message( &mut self, - _info: &super::types::ChannelInfo, + #[allow(unused)] info: &super::types::ChannelInfo, message: goval::Command, _session: SessionID, ) -> Result> { @@ -64,19 +64,11 @@ impl traits::Service for GCSFiles { let contents = match file.path.as_str() { // TODO: Read this from in the db ".env" => vec![], + #[cfg(feature = "goval-ident")] ".config/goval/info" => { - let val = serde_json::json!({ - "server": "homeval", - "version": env!("CARGO_PKG_VERSION").to_string(), - "license": "AGPL", - "authors": vec!["PotentialStyx <62217716+PotentialStyx@users.noreply.github.com>"], - "repository": "https://github.com/goval-community/homeval", - "description": "", // TODO: do dis - "uptime": 0, // TODO: impl fo realz - "services": super::IMPLEMENTED_SERVICES - }); - - val.to_string().as_bytes().to_vec() + serde_json::to_string(&info.server_info.get_serializable())? + .as_bytes() + .to_vec() } _ => match fs::read(&file.path).await { Err(err) => { diff --git a/services/src/goval_ident.rs b/services/src/goval_ident.rs new file mode 100644 index 0000000..bc90067 --- /dev/null +++ b/services/src/goval_ident.rs @@ -0,0 +1,131 @@ +pub struct GovalIdent {} + +use crate::{server_info::ServerInfoSerialize, ClientInfo, IPCMessage, SessionID}; + +use super::traits; +use anyhow::{format_err, Result}; +use async_trait::async_trait; +use serde::{Deserialize, Serialize}; +use tracing::{error, warn}; + +#[derive(Deserialize)] +enum IdentReqType { + ServerInfo, + + #[serde(untagged)] + Unknown(String), +} + +#[derive(Deserialize)] +struct IdentRequest { + r#type: IdentReqType, + r#ref: String, +} + +#[derive(Serialize)] +#[serde(untagged)] +enum IdentResponseEnum<'a> { + Error(String), + Data(ServerInfoSerialize<'a>), +} + +#[derive(Serialize)] +struct IdentResponse<'a> { + body: IdentResponseEnum<'a>, + r#ref: String, +} + +#[async_trait] +impl traits::Service for GovalIdent { + async fn message( + &mut self, + info: &super::types::ChannelInfo, + message: goval::Command, + session: SessionID, + ) -> Result> { + let body = match message.body.clone() { + None => return Err(format_err!("Expected command body")), + Some(body) => body, + }; + + match body { + goval::command::Body::ChatMessage(msg) => { + let req: IdentRequest = serde_json::from_str(&msg.text)?; + + match req.r#type { + IdentReqType::ServerInfo => { + let msg_text = serde_json::to_string(&IdentResponse { + body: IdentResponseEnum::Data(info.server_info.get_serializable()), + r#ref: req.r#ref, + })?; + + let response_body = goval::command::Body::ChatMessage(goval::ChatMessage { + username: "goval".to_string(), + text: msg_text, + }); + + let response = goval::Command { + body: Some(response_body), + ..Default::default() + }; + + Ok(Some(response)) + } + IdentReqType::Unknown(req_type) => { + error!(req_type, "Unknown `goval-ident` request type"); + + let msg_text = serde_json::to_string(&IdentResponse { + body: IdentResponseEnum::Error(format!( + "Unknown request type {req_type}" + )), + r#ref: req.r#ref, + })?; + + let response_body = goval::command::Body::ChatMessage(goval::ChatMessage { + username: "goval".to_string(), + text: msg_text, + }); + + let response = goval::Command { + body: Some(response_body), + ..Default::default() + }; + + Ok(Some(response)) + } + } + } + goval::command::Body::ChatTyping(typing) => { + warn!( + %session, + username = typing.username, + "Chat#ChatTyping isn't supported by `goval-ident`", + ); + Ok(None) + } + _ => { + warn!(cmd = ?message, "Unknown goval-ident command"); + Ok(None) + } + } + } + + async fn attach( + &mut self, + _info: &super::types::ChannelInfo, + _client: ClientInfo, + _session: SessionID, + _sender: tokio::sync::mpsc::UnboundedSender, + ) -> Result> { + let mut scrollback = goval::Command::default(); + + let _inner = goval::ChatMessage { + username: "goval".to_string(), + text: "{\"type\": \"notification\"}".to_string(), + }; + + scrollback.body = Some(goval::command::Body::ChatMessage(_inner)); + + Ok(Some(scrollback)) + } +} diff --git a/services/src/lib.rs b/services/src/lib.rs index 04e7736..022699f 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(extract_if)] +#![feature(extract_if, lazy_cell)] #![warn( clippy::pedantic, clippy::unwrap_used, @@ -36,6 +36,9 @@ mod toolchain; mod traits; mod types; +#[cfg(feature = "goval-ident")] +mod goval_ident; + use anyhow::format_err; use anyhow::Result; use std::collections::HashMap; @@ -58,7 +61,12 @@ impl Channel { dotreplit: Arc>, child_env_vars: Arc>>, sender: tokio::sync::mpsc::UnboundedSender, + + server_info: &'static ServerInfo<'static>, ) -> Result { + #[cfg(feature = "goval-ident")] + let goval_ident = name.as_deref() == Some("goval-ident"); + let info = ChannelInfo { id, name, @@ -68,10 +76,24 @@ impl Channel { sender: sender.clone(), dotreplit, child_env_vars, + + server_info, }; let channel: Box = match service.as_str() { - "chat" => Box::new(chat::Chat::new()), + "chat" => { + #[cfg(feature = "goval-ident")] + { + if goval_ident { + Box::new(goval_ident::GovalIdent {}) + } else { + Box::new(chat::Chat::new()) + } + } + + #[cfg(not(feature = "goval-ident"))] + Box::new(chat::Chat::new()) + } "gcsfiles" => Box::new(gcsfiles::GCSFiles {}), "presence" => Box::new(presence::Presence::new()), "ot" => Box::new(ot::OT::new(sender).await?), diff --git a/services/src/types/channel_info.rs b/services/src/types/channel_info.rs index f49b59f..50e5d9a 100644 --- a/services/src/types/channel_info.rs +++ b/services/src/types/channel_info.rs @@ -6,7 +6,7 @@ use tokio::sync::RwLock; use tracing::error; use crate::config::dotreplit::DotReplit; -use crate::{ChannelID, SessionID}; +use crate::{ChannelID, ServerInfo, SessionID}; use super::client::ClientInfo; use super::messaging::IPCMessage; @@ -27,6 +27,8 @@ pub struct ChannelInfo { pub sender: tokio::sync::mpsc::UnboundedSender, pub dotreplit: Arc>, pub child_env_vars: Arc>>, + + pub server_info: &'static ServerInfo<'static>, } impl ChannelInfo { diff --git a/services/src/types/fs_watcher.rs b/services/src/types/fs_watcher.rs index ff16431..a2ae38a 100644 --- a/services/src/types/fs_watcher.rs +++ b/services/src/types/fs_watcher.rs @@ -3,7 +3,6 @@ use notify_debouncer_full::{ notify::{self, event::ModifyKind, Event, EventKind, RecommendedWatcher, Watcher}, DebounceEventResult, Debouncer, }; -use serde::Serialize; use tracing::error; use anyhow::{format_err, Result}; @@ -20,8 +19,7 @@ use crate::ChannelMessage; // > = LazyLock::new(|| RwLock::new(HashMap::new())); // static MAX_WATCHER: LazyLock> = LazyLock::new(|| Mutex::new(0)); -#[derive(Serialize, Debug, Clone)] -#[serde(rename_all = "camelCase")] +#[derive(Debug, Clone)] pub enum FSEvent { Remove(String), Create(String), diff --git a/services/src/types/messaging.rs b/services/src/types/messaging.rs index 3388f43..3c7878b 100644 --- a/services/src/types/messaging.rs +++ b/services/src/types/messaging.rs @@ -1,14 +1,12 @@ use anyhow::Result; use prost::Message; -use serde::{Deserialize, Serialize}; use tokio::sync::mpsc::Sender; use crate::{SendSessions, SessionID}; use super::client::ClientInfo; -#[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "camelCase")] +#[derive(Debug, Clone)] pub enum ReplspaceMessage { GithubTokenReq(String), // nonce OpenFileReq(String, bool, String), // file, wait for close, nonce diff --git a/services/src/types/mod.rs b/services/src/types/mod.rs index ebc1ce2..f6536fd 100644 --- a/services/src/types/mod.rs +++ b/services/src/types/mod.rs @@ -1,6 +1,9 @@ pub mod channel_info; pub use channel_info::{ChannelInfo, SendSessions}; +pub mod server_info; +pub use server_info::ServerInfo; + pub mod messaging; pub use messaging::{ChannelMessage, IPCMessage, ReplspaceMessage}; diff --git a/services/src/types/server_info.rs b/services/src/types/server_info.rs new file mode 100644 index 0000000..ea781be --- /dev/null +++ b/services/src/types/server_info.rs @@ -0,0 +1,46 @@ +use std::{sync::LazyLock, time::Instant}; + +#[cfg(feature = "goval-ident")] +use serde::Serialize; + +pub struct ServerInfo<'a> { + pub name: &'a str, + pub version: &'a str, + pub license: &'a str, + pub repository: &'a str, + pub description: &'a str, + + pub start_time: &'a LazyLock, + + // TODO: make this &[&str] (is this easily possible?) + pub authors: &'a LazyLock>, +} + +#[cfg(feature = "goval-ident")] +#[derive(Serialize, Debug)] +pub struct ServerInfoSerialize<'a> { + pub server: &'a str, + pub version: &'a str, + pub license: &'a str, + pub authors: &'a [&'a str], + pub repository: &'a str, + pub description: &'a str, + pub uptime: u64, + pub services: &'a [&'a str], +} + +#[cfg(feature = "goval-ident")] +impl<'a> ServerInfo<'a> { + pub fn get_serializable(&self) -> ServerInfoSerialize<'a> { + ServerInfoSerialize { + server: self.name, + version: self.version, + license: self.license, + authors: self.authors, + repository: self.repository, + description: self.description, + uptime: self.start_time.elapsed().as_secs(), + services: crate::IMPLEMENTED_SERVICES, + } + } +} diff --git a/src/goval_server.rs b/src/goval_server.rs index 2b23ddc..2e3496d 100644 --- a/src/goval_server.rs +++ b/src/goval_server.rs @@ -26,8 +26,8 @@ use tokio::sync::mpsc; use tracing::{debug, error, info, trace, warn}; use crate::{ - parse_paseto::parse, ChannelMessage, IPCMessage, CHANNEL_MESSAGES, CHILD_PROCS_ENV_BASE, - DOTREPLIT_CONFIG, LAST_SESSION_USING_CHANNEL, + parse_paseto::parse, server_info::SERVER_INFO, ChannelMessage, IPCMessage, CHANNEL_MESSAGES, + CHILD_PROCS_ENV_BASE, DOTREPLIT_CONFIG, LAST_SESSION_USING_CHANNEL, }; static MAX_SESSION: LazyLock> = LazyLock::new(|| Mutex::new(0)); @@ -281,6 +281,7 @@ async fn open_channel( DOTREPLIT_CONFIG.clone(), CHILD_PROCS_ENV_BASE.clone(), writer, + &SERVER_INFO, ) .await .expect("TODO: Deal with this"); diff --git a/src/main.rs b/src/main.rs index 2842b75..2aa989e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,11 +7,10 @@ )] use anyhow::Result; +use homeval_services::{ChannelID, SessionID}; use std::sync::LazyLock; use std::time::Instant; use std::{collections::HashMap, sync::Arc}; - -use homeval_services::{ChannelID, SessionID}; use tokio::sync::RwLock; use tracing::{debug, info}; @@ -31,6 +30,9 @@ mod replspace_server; #[cfg(feature = "repldb")] mod repldb_server; +mod server_info; +pub use server_info::SERVER_INFO; + pub static START_TIME: LazyLock = LazyLock::new(Instant::now); static CPU_STATS: LazyLock> = LazyLock::new(|| Arc::new(cpu_time::ProcessTime::now())); @@ -68,6 +70,7 @@ async fn main() -> Result<()> { debug!("Initializing lazy statics"); LazyLock::force(&START_TIME); LazyLock::force(&CPU_STATS); + LazyLock::force(SERVER_INFO.authors); debug!("Lazy statics initialized successfully"); diff --git a/src/server_info.rs b/src/server_info.rs new file mode 100644 index 0000000..c954de7 --- /dev/null +++ b/src/server_info.rs @@ -0,0 +1,16 @@ +use std::sync::LazyLock; + +use homeval_services::ServerInfo; + +static SERVER_AUTHORS: LazyLock> = + LazyLock::new(|| env!("CARGO_PKG_AUTHORS").split(':').collect()); + +pub static SERVER_INFO: ServerInfo = ServerInfo { + name: env!("CARGO_PKG_NAME"), + version: env!("CARGO_PKG_VERSION"), + license: env!("CARGO_PKG_LICENSE"), + repository: env!("CARGO_PKG_REPOSITORY"), + description: env!("CARGO_PKG_DESCRIPTION"), + start_time: &crate::START_TIME, + authors: &SERVER_AUTHORS, +}; From 72e2389379f26e303d5ce9782966b92a069fbe6f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Apr 2024 13:09:13 +0000 Subject: [PATCH 101/103] build(deps): bump base64 from 0.21.7 to 0.22.0 Bumps [base64](https://github.com/marshallpierce/rust-base64) from 0.21.7 to 0.22.0. - [Changelog](https://github.com/marshallpierce/rust-base64/blob/master/RELEASE-NOTES.md) - [Commits](https://github.com/marshallpierce/rust-base64/compare/v0.21.7...v0.22.0) --- updated-dependencies: - dependency-name: base64 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 +++++++- Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1b9bc3..333046c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -270,6 +270,12 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +[[package]] +name = "base64" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" + [[package]] name = "base64ct" version = "1.6.0" @@ -1087,7 +1093,7 @@ version = "0.3.0" dependencies = [ "anyhow", "axum", - "base64 0.21.7", + "base64 0.22.0", "chrono", "chrono-tz", "cpu-time", diff --git a/Cargo.toml b/Cargo.toml index 0b2b06d..11ca0b2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ prost-types = "0.12.3" serde_json = "1.0.115" serde = { version = "1.0.197", features = ["derive"] } tokio = {version="1.36.0", features = ["full"]} -base64 = "0.21.0" +base64 = "0.22.0" futures = "0.3.28" axum = { version = "0.7.5", features = ["ws"] } cpu-time = "1.0.0" From 644bbb4056b9ab376f05f94eaca68ae3e05f7ef8 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 18 May 2024 13:06:14 -0700 Subject: [PATCH 102/103] fix(services): Fix fs update -> replit ot catchup --- services/src/ot.rs | 79 ++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/services/src/ot.rs b/services/src/ot.rs index 61e4d69..4706ad2 100644 --- a/services/src/ot.rs +++ b/services/src/ot.rs @@ -18,9 +18,11 @@ use crate::{client::ClientInfo, fs_watcher::FSWatcher, FSEvent, IPCMessage, Sess use super::traits; use anyhow::{format_err, Result}; use async_trait::async_trait; +use crc32fast::Hasher; +use goval::{ot_op_component::OpComponent, OtOpComponent}; use ropey::Rope; use similar::TextDiff; -use tokio::fs; +use tokio::{fs, io::AsyncWriteExt}; use tracing::{debug, error, trace, warn}; impl OT { @@ -122,40 +124,6 @@ impl traits::Service for OT { self.watcher.watch(vec![path])?; - // let mut reader = self.watcher.get_event_reader().await; - // let sending_map = self._sending_map.clone(); - // let file_path = self.path.clone(); - // let crc32 = self.crc32.clone(); - // let contents = self.contents.clone(); - // let version = self.version.clone(); - // let history = self.history.clone(); - // let channel_id = info.id.clone(); - // tokio::spawn(async move { - // loop { - // let res = async { - // match reader.recv().await { - // Ok(res) => { - - // LoopControl::Cont(Ok(())) - // } - // Err(err) => match err { - // RecvError::Closed => LoopControl::Break, - // RecvError::Lagged(ammount) => { - // warn!(messages = ammount; "FSEvents lagged"); - // LoopControl::Cont(Ok(())) - // } - // }, - // } - // } - // .await; - - // match res { - // LoopControl::Break => break, - // LoopControl::Cont(result) => result.expect("TODO: deal with this"), - // } - // } - // }); - return Ok(Some(link_response)); } @@ -208,9 +176,7 @@ impl traits::Service for OT { } } - let to_write = self.contents.to_string(); self.version += 1; - // drop(version); let user_id; if ot.author == goval::ot_packet::Author::Ghostwriter as i32 { @@ -221,7 +187,27 @@ impl traits::Service for OT { user_id = 23_054_564; // https://replit.com/@homeval-user } - let crc32 = crc32fast::hash(to_write.as_bytes()); + let mut crc32_hasher = Hasher::new(); //crc32fast::hash(to_write.as_bytes()); + let mut file_writer = fs::OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(&self.path) + .await?; + + for chunk in self.contents.chunks() { + let bytes = chunk.as_bytes(); + + crc32_hasher.update(bytes); + file_writer.write_all(bytes).await?; + } + + file_writer.flush().await?; + file_writer.sync_data().await?; + + drop(file_writer); + + let crc32 = crc32_hasher.finalize(); self.crc32 = crc32; let committed = Some(prost_types::Timestamp { @@ -249,8 +235,6 @@ impl traits::Service for OT { info.send(ot_notif, crate::SendSessions::Everyone)?; - fs::write(&self.path, to_write).await?; - let ok = goval::Command { body: Some(goval::command::Body::Ok(goval::Ok {})), ..Default::default() @@ -337,7 +321,20 @@ impl traits::Service for OT { let new_contents = String::from_utf8(new_contents).expect("TODO: Deal with this"); + // let new_contents_str: &str = &new_contents; + // let new_self_contents = new_contents_str.into(); + let ops = diff(&self.contents.to_string(), &new_contents); + // let ops = vec![ + // OtOpComponent { + // op_component: Some(OpComponent::Delete( + // self.contents.len_chars() as u32 + // )), + // }, + // OtOpComponent { + // op_component: Some(OpComponent::Insert(new_contents)), + // }, + // ]; self.contents = new_contents.into(); self.crc32 = new_crc32; @@ -427,7 +424,7 @@ impl traits::Service for OT { fn diff(old_text: &str, new_text: &str) -> Vec { let mut differ_config: similar::TextDiffConfig = TextDiff::configure(); - let differ = differ_config.timeout(Duration::from_secs(1)); + let differ = differ_config.timeout(Duration::from_secs_f32(0.3)); let diff = differ.diff_chars(old_text, new_text); let mut parts: Vec = vec![]; From 666884c86e744d7354c793059330c2dd68e53ac1 Mon Sep 17 00:00:00 2001 From: PotentialStyx <62217716+PotentialStyx@users.noreply.github.com> Date: Sat, 18 May 2024 13:10:31 -0700 Subject: [PATCH 103/103] refactor(services): Remove stubbed audio service Replit is removing the audio service soon (see: replit/replit-py#219) --- services/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/services/src/lib.rs b/services/src/lib.rs index 022699f..dfbbb24 100644 --- a/services/src/lib.rs +++ b/services/src/lib.rs @@ -105,7 +105,7 @@ impl Channel { "exec" => Box::new(exec::Exec::new()), "dotreplit" => Box::new(dotreplit::DotReplit {}), "fsevents" => Box::new(fsevents::FSEvents::new(sender).await?), - "audio" | "null" => Box::new(stub::Stub {}), // Audio will never be supported and null does nothing + "null" => Box::new(stub::Stub {}), // Null does nothing _ => return Err(format_err!("Unknown service: {}", service)), }; @@ -205,7 +205,6 @@ pub static IMPLEMENTED_SERVICES: &[&str] = &[ "snapshot", "null", "git", - "audio", "output", "shell", "toolchain",