Skip to content

Commit

Permalink
Make spacetime version always succeed
Browse files Browse the repository at this point in the history
  • Loading branch information
coolreader18 committed Jan 17, 2025
1 parent 416e3fd commit 1307a51
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 42 deletions.
2 changes: 1 addition & 1 deletion crates/update/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl Args {
if let Some(root_dir) = &self.root_dir {
cli_args.insert(0, OsString::from_iter(["--root-dir=".as_ref(), root_dir.as_ref()]));
}
crate::proxy::run_cli(&paths, None, cli_args)
crate::proxy::run_cli(Some(&paths), None, cli_args)
}
Subcommand::Version(version) => version.exec(&paths).map(|()| ExitCode::SUCCESS),
}
Expand Down
2 changes: 1 addition & 1 deletion crates/update/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ fn main() -> anyhow::Result<ExitCode> {
if cmd == "spacetimedb-update" {
spacetimedb_update_main()
} else if cmd == "spacetime" {
proxy::spacetimedb_cli_proxy(Some(argv0.as_os_str()), args.collect())
proxy::run_cli(None, Some(argv0.as_os_str()), args.collect())
} else {
anyhow::bail!(
"unknown command name for spacetimedb-update multicall binary: {}",
Expand Down
121 changes: 81 additions & 40 deletions crates/update/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,26 @@ use std::path::PathBuf;
use std::process::Command;
use std::process::ExitCode;

pub(super) fn spacetimedb_cli_proxy(argv0: Option<&OsStr>, args: Vec<OsString>) -> anyhow::Result<ExitCode> {
let paths = match extract_root_dir_arg(&args)? {
Some(root_dir) => SpacetimePaths::from_root_dir(&root_dir),
None => SpacetimePaths::platform_defaults()?,
pub(crate) fn run_cli(
paths: Option<&SpacetimePaths>,
argv0: Option<&OsStr>,
args: Vec<OsString>,
) -> anyhow::Result<ExitCode> {
let parse_args = || PartialCliArgs::parse(&args);
let mut is_version_subcommand = None;
let paths_;
let paths = match paths {
Some(paths) => paths,
None => {
let partial_args = parse_args()?;
is_version_subcommand = Some(partial_args.is_version_subcommand());
paths_ = match partial_args.root_dir {
Some(root_dir) => SpacetimePaths::from_root_dir(&root_dir),
None => SpacetimePaths::platform_defaults()?,
};
&paths_
}
};
run_cli(&paths, argv0, args)
}
pub(crate) fn run_cli(paths: &SpacetimePaths, argv0: Option<&OsStr>, args: Vec<OsString>) -> anyhow::Result<ExitCode> {
let cli_path = if let Some(artifact_dir) = running_from_target_dir() {
let cli_path = spacetimedb_paths::cli::VersionBinDir::from_path_unchecked(artifact_dir).spacetimedb_cli();
anyhow::ensure!(
Expand All @@ -25,24 +37,35 @@ pub(crate) fn run_cli(paths: &SpacetimePaths, argv0: Option<&OsStr>, args: Vec<O
} else {
paths.cli_bin_dir.current_version_dir().spacetimedb_cli()
};

let mut cmd = Command::new(&cli_path);
cmd.args(args);
cmd.args(&args);
#[cfg(unix)]
{
let exec_err = {
use std::os::unix::process::CommandExt;
if let Some(argv0) = argv0 {
cmd.arg0(argv0);
}
let err = cmd.exec();
Err(err).context(format!("exec failed for {}", cli_path.display()))
}
cmd.exec()
};
#[cfg(windows)]
{
let status = cmd
.status()
.with_context(|| format!("failed to run {}", cli_path.display()))?;
Ok(ExitCode::from(status.code().unwrap_or(1) as u8))
let exec_err = {
match cmd.status() {
Ok(status) => return Ok(ExitCode::from(status.code().unwrap_or(1) as u8)),
Err(err) => err,
}
};
// if we failed to exec cli and it seems like the user is trying to run `spacetime version`,
// patch them through directly.
if is_version_subcommand.unwrap_or_else(|| parse_args().is_ok_and(|a| a.is_version_subcommand())) {
return crate::spacetimedb_update_main();
}
Err(exec_err)
.context(format!("exec failed for {}", cli_path.display()))
.context(
"It seems like the spacetime version set as current may not exist. Try using `spacetime version`\n\
to set a different version as default or to install a new version altogether.",
)
}

/// Checks to see if we're running from a subdirectory of a `target` dir that has a `Cargo.toml`
Expand All @@ -65,31 +88,49 @@ pub(crate) fn running_from_target_dir() -> Option<PathBuf> {
.map(|_| artifact_dir)
}

fn extract_root_dir_arg(args: &[OsString]) -> anyhow::Result<Option<RootDir>> {
let mut args = args.iter();
let mut root_dir = None;
while let Some(arg) = args.next() {
let is_arg_value = |s: &OsStr| !os_str_starts_with(arg, "-") || s == "-";
// "parse" only up to the first subcommand
if is_arg_value(arg) || arg == "--" {
break;
struct PartialCliArgs<'a> {
root_dir: Option<RootDir>,
maybe_subcommand: Option<&'a OsStr>,
}

impl<'a> PartialCliArgs<'a> {
fn is_version_subcommand(&self) -> bool {
self.maybe_subcommand.is_some_and(|s| s == "version")
}

fn parse(args: &'a [OsString]) -> anyhow::Result<Self> {
let mut args = args.iter();
let mut root_dir = None;
let mut maybe_subcommand = None;
while let Some(arg) = args.next() {
let is_arg_value = |s: &OsStr| !os_str_starts_with(arg, "-") || s == "-";
// "parse" only up to the first subcommand
if is_arg_value(arg) {
maybe_subcommand = Some(&**arg);
break;
} else if arg == "--" {
break;
}
let root_dir_arg = if arg == "--root-dir" {
args.next()
.filter(|s| is_arg_value(s))
.context("a value is required for '--root-dir <root_dir>' but none was supplied")?
} else if let Some(arg) = os_str_strip_prefix(arg, "--root-dir=") {
arg
} else {
continue;
};
anyhow::ensure!(
root_dir.is_none(),
"the argument '--root-dir <root_dir>' cannot be used multiple times"
);
root_dir = Some(RootDir(root_dir_arg.into()));
}
let root_dir_arg = if arg == "--root-dir" {
args.next()
.filter(|s| is_arg_value(s))
.context("a value is required for '--root-dir <root_dir>' but none was supplied")?
} else if let Some(arg) = os_str_strip_prefix(arg, "--root-dir=") {
arg
} else {
continue;
};
anyhow::ensure!(
root_dir.is_none(),
"the argument '--root-dir <root_dir>' cannot be used multiple times"
);
root_dir = Some(RootDir(root_dir_arg.into()));
Ok(Self {
root_dir,
maybe_subcommand,
})
}
Ok(root_dir)
}

fn os_str_starts_with(s: &OsStr, pref: &str) -> bool {
Expand Down

0 comments on commit 1307a51

Please sign in to comment.