Skip to content

Commit

Permalink
Split binaries
Browse files Browse the repository at this point in the history
  • Loading branch information
coolreader18 committed Dec 17, 2024
1 parent 1b31209 commit 699d806
Show file tree
Hide file tree
Showing 23 changed files with 408 additions and 137 deletions.
12 changes: 11 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ members = [
"crates/standalone",
"crates/table",
"crates/testing",
"crates/update",
"crates/vm",
"modules/benchmarks",
"modules/perf-test",
Expand Down
7 changes: 1 addition & 6 deletions crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ rust-version.workspace = true
bench = false

[[bin]]
name = "spacetime"
name = "spacetimedb-cli"
path = "src/main.rs"
# Benching off, because of https://bheisler.github.io/criterion.rs/book/faq.html#cargo-bench-gives-unrecognized-option-errors-for-valid-command-line-options
bench = false
Expand All @@ -26,7 +26,6 @@ spacetimedb-lib.workspace = true
spacetimedb-paths.workspace = true
spacetimedb-primitives.workspace = true
spacetimedb-schema.workspace = true
spacetimedb-standalone = { workspace = true, optional = true }

anyhow.workspace = true
base64.workspace = true
Expand Down Expand Up @@ -71,7 +70,3 @@ webbrowser.workspace = true
insta.workspace = true
fs-err.workspace = true
spacetimedb-testing = { path = "../testing" }

[features]
standalone = ["spacetimedb-standalone"]
default = ["standalone"]
16 changes: 7 additions & 9 deletions crates/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,20 @@ mod config;
pub(crate) mod detect;
mod edit_distance;
mod errors;
mod start;
mod subcommands;
mod tasks;
pub mod util;

use std::process::ExitCode;

use clap::{ArgMatches, Command};

pub use config::Config;
use spacetimedb_paths::SpacetimePaths;
use spacetimedb_standalone::subcommands::start::ProgramMode;
pub use subcommands::*;
pub use tasks::build;

#[cfg(feature = "standalone")]
use spacetimedb_standalone::subcommands::start;

pub fn get_subcommands() -> Vec<Command> {
vec![
version::cli(),
Expand All @@ -39,8 +38,7 @@ pub fn get_subcommands() -> Vec<Command> {
server::cli(),
upgrade::cli(),
subscribe::cli(),
#[cfg(feature = "standalone")]
start::cli(ProgramMode::CLI),
start::cli(),
]
}

Expand All @@ -49,7 +47,7 @@ pub async fn exec_subcommand(
paths: &SpacetimePaths,
cmd: &str,
args: &ArgMatches,
) -> Result<(), anyhow::Error> {
) -> anyhow::Result<ExitCode> {
match cmd {
"version" => version::exec(config, args).await,
"call" => call::exec(config, args).await,
Expand All @@ -66,11 +64,11 @@ pub async fn exec_subcommand(
"build" => build::exec(config, args).await.map(drop),
"server" => server::exec(config, paths, args).await,
"subscribe" => subscribe::exec(config, args).await,
#[cfg(feature = "standalone")]
"start" => start::exec(Some(paths), args).await,
"start" => return start::exec(paths, args).await,
"login" => login::exec(config, args).await,
"logout" => logout::exec(config, args).await,
"upgrade" => upgrade::exec(config, args).await,
unknown => Err(anyhow::anyhow!("Invalid subcommand: {}", unknown)),
}
.map(|()| ExitCode::SUCCESS)
}
8 changes: 4 additions & 4 deletions crates/cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::process::ExitCode;

use clap::{Arg, Command};
use mimalloc::MiMalloc;
use spacetimedb_cli::*;
Expand All @@ -8,7 +10,7 @@ use spacetimedb_paths::{RootDir, SpacetimePaths};
static GLOBAL: MiMalloc = MiMalloc;

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
async fn main() -> anyhow::Result<ExitCode> {
// Compute matches before loading the config, because `Config` has an observable `drop` method
// (which deletes a lockfile),
// and Clap calls `exit` on parse failure rather than panicing, so destructors never run.
Expand All @@ -25,9 +27,7 @@ async fn main() -> Result<(), anyhow::Error> {
.unwrap_or_else(|| paths.cli_config_dir.cli_toml());
let config = Config::load(cli_toml)?;

exec_subcommand(config, &paths, cmd, subcommand_args).await?;

Ok(())
exec_subcommand(config, &paths, cmd, subcommand_args).await
}

fn get_command() -> Command {
Expand Down
68 changes: 68 additions & 0 deletions crates/cli/src/start.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use std::ffi::OsString;
use std::process::{Command, ExitCode};

use anyhow::Context;
use clap::{Arg, ArgMatches};
use spacetimedb_paths::SpacetimePaths;

pub fn cli() -> clap::Command {
clap::Command::new("start")
.about("Start a local SpacetimeDB instance")
.disable_help_flag(true)
.arg(
Arg::new("edition")
.long("edition")
.help("The edition of SpacetimeDB to start up")
.value_parser(clap::value_parser!(Edition))
.default_value("standalone"),
)
.arg(
Arg::new("args")
.help("The args to pass to `spacetimedb-{edition} start`")
.value_parser(clap::value_parser!(OsString))
.allow_hyphen_values(true)
.num_args(0..),
)
}

#[derive(clap::ValueEnum, Clone, Copy)]
enum Edition {
Standalone,
Cloud,
}

pub async fn exec(paths: &SpacetimePaths, args: &ArgMatches) -> anyhow::Result<ExitCode> {
let edition = args.get_one::<Edition>("edition").unwrap();
let args = args.get_many::<OsString>("args").unwrap_or_default();
let bin_name = match edition {
Edition::Standalone => "spacetimedb-standalone",
Edition::Cloud => "spacetimedb-cloud",
};
let resolved_exe = std::env::current_exe().context("could not retrieve current exe")?;
let bin_path = resolved_exe
.parent()
.unwrap()
.join(bin_name)
.with_extension(std::env::consts::EXE_EXTENSION);
let mut cmd = Command::new(&bin_path);
cmd.arg("start")
.arg("--data-dir")
.arg(&paths.data_dir)
.arg("--jwt-key-dir")
.arg(&paths.cli_config_dir)
.args(args);
#[cfg(unix)]
{
use std::os::unix::process::CommandExt;
let err = cmd.exec();
Err(err).context(format!("exec failed for {}", bin_path.display()))
}
#[cfg(windows)]
{
use std::os::windows::process::ExitCodeExt;
let status = cmd
.status()
.with_context(|| format!("failed to run {}", cli_path.display()))?;
Ok(ExitCode::from_raw(status.code().unwrap_or(1) as u32))
}
}
6 changes: 4 additions & 2 deletions crates/cli/src/subcommands/subscribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use spacetimedb_data_structures::map::HashMap;
use spacetimedb_lib::db::raw_def::v9::RawModuleDefV9;
use spacetimedb_lib::de::serde::{DeserializeWrapper, SeedWrapper};
use spacetimedb_lib::ser::serde::SerializeWrapper;
use spacetimedb_standalone::TEXT_PROTOCOL;
use std::time::Duration;
use tokio::io::AsyncWriteExt;
use tokio_tungstenite::tungstenite::client::IntoClientRequest;
Expand Down Expand Up @@ -144,7 +143,10 @@ pub async fn exec(config: Config, args: &ArgMatches) -> Result<(), anyhow::Error

// Create the websocket request.
let mut req = http::Uri::from_parts(uri)?.into_client_request()?;
req.headers_mut().insert(header::SEC_WEBSOCKET_PROTOCOL, TEXT_PROTOCOL);
req.headers_mut().insert(
header::SEC_WEBSOCKET_PROTOCOL,
http::HeaderValue::from_static(ws::TEXT_PROTOCOL),
);
// Add the authorization header, if any.
if let Some(auth_header) = &api.con.auth_header {
req.headers_mut().insert(header::AUTHORIZATION, auth_header.try_into()?);
Expand Down
3 changes: 3 additions & 0 deletions crates/client-api-messages/src/websocket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ use std::{
sync::Arc,
};

pub const TEXT_PROTOCOL: &str = "v1.json.spacetimedb";
pub const BIN_PROTOCOL: &str = "v1.bsatn.spacetimedb";

pub trait RowListLen {
/// Returns the length of the list.
fn len(&self) -> usize;
Expand Down
6 changes: 3 additions & 3 deletions crates/client-api/src/routes/subscribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use spacetimedb::client::{ClientActorId, ClientConfig, ClientConnection, DataMes
use spacetimedb::host::NoSuchModule;
use spacetimedb::util::also_poll;
use spacetimedb::worker_metrics::WORKER_METRICS;
use spacetimedb_client_api_messages::websocket::Compression;
use spacetimedb_client_api_messages::websocket::{self as ws_api, Compression};
use spacetimedb_lib::address::AddressForUrl;
use spacetimedb_lib::Address;
use std::time::Instant;
Expand All @@ -31,9 +31,9 @@ use crate::util::{NameOrIdentity, XForwardedFor};
use crate::{log_and_500, ControlStateDelegate, NodeDelegate};

#[allow(clippy::declare_interior_mutable_const)]
pub const TEXT_PROTOCOL: HeaderValue = HeaderValue::from_static("v1.json.spacetimedb");
pub const TEXT_PROTOCOL: HeaderValue = HeaderValue::from_static(ws_api::TEXT_PROTOCOL);
#[allow(clippy::declare_interior_mutable_const)]
pub const BIN_PROTOCOL: HeaderValue = HeaderValue::from_static("v1.bsatn.spacetimedb");
pub const BIN_PROTOCOL: HeaderValue = HeaderValue::from_static(ws_api::BIN_PROTOCOL);

#[derive(Deserialize)]
pub struct SubscribeParams {
Expand Down
4 changes: 2 additions & 2 deletions crates/core/src/db/relational_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1195,10 +1195,10 @@ struct LockFile {
impl LockFile {
pub fn lock(root: &ReplicaDir) -> Result<Self, DBError> {
root.create()?;
let path = root.as_ref().join("db.lock");
let path = root.0.join("db.lock");
let lock = File::create(&path)?;
lock.try_lock_exclusive()
.map_err(|e| DatabaseError::DatabasedOpened(root.as_ref().to_path_buf(), e.into()))?;
.map_err(|e| DatabaseError::DatabasedOpened(root.0.clone(), e.into()))?;

Ok(Self {
path: path.into(),
Expand Down
1 change: 1 addition & 0 deletions crates/paths/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ anyhow.workspace = true
chrono = { workspace = true, features = ["now"] }
fs2.workspace = true
itoa.workspace = true
semver.workspace = true
serde.workspace = true
thiserror.workspace = true

Expand Down
19 changes: 18 additions & 1 deletion crates/paths/src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::utils::path_type;
use crate::utils::{path_type, PathBufExt};

path_type! {
/// The configuration directory for the CLI & keyfiles.
Expand All @@ -21,6 +21,23 @@ path_type!(#[non_exhaustive(FALSE)] PrivKeyPath: file);
path_type!(#[non_exhaustive(FALSE)] PubKeyPath: file);

path_type!(BinFile: file);

path_type!(BinDir: dir);

impl BinDir {
pub fn version_dir(&self, version: semver::Version) -> VersionBinDir {
VersionBinDir(self.0.join(version.to_string()))
}
}

path_type!(VersionBinDir: dir);

impl VersionBinDir {
pub fn spacetimedb_cli(self) -> SpacetimedbCliBin {
SpacetimedbCliBin(self.0.joined("spacetimedb-cli").with_exe_ext())
}
}

path_type!(SpacetimedbCliBin: file);

path_type!(CliTomlPath: file);
11 changes: 2 additions & 9 deletions crates/paths/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,6 @@
//! └── 040a8585e6dc2c579c0c8f6017c7e6a0179a5d0410cd8db4b4affbd7d4d04f
//! ```
use std::env::consts::EXE_EXTENSION;

use crate::utils::PathBufExt;

pub mod cli;
Expand Down Expand Up @@ -185,9 +183,7 @@ impl RootDir {
}

pub fn cli_bin_file(&self) -> cli::BinFile {
let mut path = self.0.join("spacetime");
path.set_extension(EXE_EXTENSION);
cli::BinFile(path)
cli::BinFile(self.0.join("spacetime").with_exe_ext())
}

pub fn cli_bin_dir(&self) -> cli::BinDir {
Expand Down Expand Up @@ -320,10 +316,7 @@ mod tests {
let root = Path::new("/custom/path");
let paths = SpacetimePaths::from_root_dir(&RootDir(root.to_owned()));
assert_eq!(paths.cli_config_dir.0, root.join("config"));
assert_eq!(
paths.cli_bin_file.0,
root.join("spacetime").with_extension(EXE_EXTENSION)
);
assert_eq!(paths.cli_bin_file.0, root.join("spacetime").with_exe_ext());
assert_eq!(paths.cli_bin_dir.0, root.join("bin"));
assert_eq!(paths.data_dir.0, root.join("data"));
}
Expand Down
Loading

0 comments on commit 699d806

Please sign in to comment.