Skip to content

Commit 350066a

Browse files
spacetime dev - Fix file watcher ignoring --module-path / spacetime.json module_path (#4464)
## Summary Fixes #4443 — `spacetime dev` ignores both `--module-path` CLI flag and `module-path` in `spacetime.json` for the file watcher, always watching `<project-path>/spacetimedb/` instead. ## Root Cause Two bugs: 1. **Config's `module-path` never applied to `spacetimedb_dir`**: When `spacetime.json` contains `module-path`, the recovery prompt is correctly skipped (the code checks for its existence), but the value is never used to update `spacetimedb_dir`. It stays as `project_dir/spacetimedb`. 2. **Hardcoded fallback in `determine_publish_configs()`**: When there are no publish targets in config (no `database` key or `children`), the fallback creates a publish config entry with `module-path: "spacetimedb"` hardcoded. This propagates to `extract_watch_dirs()` (file watcher) and the publish loop, overriding any CLI or config value. ## Fix 1. After loading config, resolve `spacetimedb_dir` from config's `module-path` in `additional_fields` when CLI did not provide `--module-path`. 2. Pass the resolved `spacetimedb_dir` to `determine_publish_configs()` as `default_module_path` so the fallback uses the correct path instead of hardcoding `"spacetimedb"`. ## Testing - All 5 existing `determine_publish_configs` tests pass - Added new test `test_determine_publish_configs_fallback_uses_provided_module_path` that verifies the fallback uses the provided path --------- Co-authored-by: clockwork-labs-bot <clockwork-labs-bot@users.noreply.github.com> Co-authored-by: Zeke Foppa <196249+bfops@users.noreply.github.com>
1 parent 9f47647 commit 350066a

1 file changed

Lines changed: 57 additions & 3 deletions

File tree

  • crates/cli/src/subcommands

crates/cli/src/subcommands/dev.rs

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,19 @@ pub async fn exec(mut config: Config, args: &ArgMatches) -> Result<(), anyhow::E
290290
}
291291
}
292292

293+
// If config has a module-path and CLI didn't provide one, resolve spacetimedb_dir from it.
294+
// This handles the case where spacetime.json specifies module-path but has no publish targets.
295+
if module_path_from_cli.is_none() {
296+
if let Some(config_module_path) = loaded_config
297+
.as_ref()
298+
.and_then(|lc| lc.config.additional_fields.get("module-path"))
299+
.and_then(|v| v.as_str())
300+
{
301+
let p = PathBuf::from(config_module_path);
302+
spacetimedb_dir = if p.is_absolute() { p } else { project_dir.join(p) };
303+
}
304+
}
305+
293306
let spacetime_config = loaded_config.as_ref().map(|lc| &lc.config);
294307
// A config has publish targets if it has a "database" field or children
295308
let has_publish_targets_in_config = spacetime_config
@@ -365,6 +378,7 @@ pub async fn exec(mut config: Config, args: &ArgMatches) -> Result<(), anyhow::E
365378
&publish_schema,
366379
&publish_args,
367380
resolved_server,
381+
&spacetimedb_dir,
368382
)?;
369383

370384
// Check if we are in a SpacetimeDB project directory, but only if we don't have any
@@ -470,6 +484,7 @@ pub async fn exec(mut config: Config, args: &ArgMatches) -> Result<(), anyhow::E
470484
&publish_schema,
471485
&publish_args,
472486
resolved_server,
487+
&spacetimedb_dir,
473488
)?;
474489
}
475490

@@ -846,6 +861,7 @@ fn determine_publish_configs<'a>(
846861
publish_schema: &'a CommandSchema,
847862
publish_args: &'a ArgMatches,
848863
resolved_server: &str,
864+
default_module_path: &Path,
849865
) -> anyhow::Result<Vec<CommandConfig<'a>>> {
850866
// Build publish configs. It is easier to work with one type of data,
851867
// so if we don't have publish configs from the config file, we build a single
@@ -869,7 +885,7 @@ fn determine_publish_configs<'a>(
869885
let mut config_map = HashMap::new();
870886
config_map.insert("database".to_string(), json!(db_name));
871887
config_map.insert("server".to_string(), json!(resolved_server));
872-
config_map.insert("module-path".to_string(), json!("spacetimedb"));
888+
config_map.insert("module-path".to_string(), json!(default_module_path.to_string_lossy()));
873889

874890
Ok(vec![CommandConfig::new(publish_schema, config_map, publish_args)?])
875891
} else {
@@ -1728,8 +1744,16 @@ mod tests {
17281744
let publish_schema = publish::build_publish_schema(&publish_cmd).unwrap();
17291745
let publish_args = publish_cmd.clone().get_matches_from(vec!["publish"]);
17301746

1731-
let result =
1732-
determine_publish_configs(None, None, &publish_cmd, &publish_schema, &publish_args, "local").unwrap();
1747+
let result = determine_publish_configs(
1748+
None,
1749+
None,
1750+
&publish_cmd,
1751+
&publish_schema,
1752+
&publish_args,
1753+
"local",
1754+
Path::new("spacetimedb"),
1755+
)
1756+
.unwrap();
17331757

17341758
assert!(result.is_empty());
17351759
}
@@ -1748,6 +1772,7 @@ mod tests {
17481772
&publish_schema,
17491773
&publish_args,
17501774
"local",
1775+
Path::new("spacetimedb"),
17511776
)
17521777
.unwrap();
17531778

@@ -1783,6 +1808,7 @@ mod tests {
17831808
&publish_schema,
17841809
&publish_args,
17851810
"local",
1811+
Path::new("spacetimedb"),
17861812
)
17871813
.unwrap();
17881814

@@ -1814,6 +1840,7 @@ mod tests {
18141840
&publish_schema,
18151841
&publish_args,
18161842
"local",
1843+
Path::new("spacetimedb"),
18171844
)
18181845
.unwrap();
18191846

@@ -1825,6 +1852,33 @@ mod tests {
18251852
);
18261853
}
18271854

1855+
#[test]
1856+
fn test_determine_publish_configs_fallback_uses_provided_module_path() {
1857+
// When falling through to CLI database, the fallback should use the provided
1858+
// default_module_path instead of hardcoding "spacetimedb"
1859+
let publish_cmd = publish::cli();
1860+
let publish_schema = publish::build_publish_schema(&publish_cmd).unwrap();
1861+
let publish_args = publish_cmd.clone().get_matches_from(vec!["publish", "my-db"]);
1862+
1863+
let custom_path = Path::new("/custom/module/path");
1864+
let result = determine_publish_configs(
1865+
Some("my-db".to_string()),
1866+
None,
1867+
&publish_cmd,
1868+
&publish_schema,
1869+
&publish_args,
1870+
"local",
1871+
custom_path,
1872+
)
1873+
.unwrap();
1874+
1875+
assert_eq!(result.len(), 1);
1876+
assert_eq!(
1877+
result[0].get_config_value("module_path").and_then(|v| v.as_str()),
1878+
Some("/custom/module/path")
1879+
);
1880+
}
1881+
18281882
#[test]
18291883
fn test_cli_env_flag_defaults_to_dev() {
18301884
// Verify that the dev CLI defaults --env to "dev"

0 commit comments

Comments
 (0)