Skip to content

Commit 5565f8d

Browse files
committed
gnd: Fix manifest_dir to handle bare filenames like "subgraph.yaml"
When manifest_path is a bare filename without directory component, Path::parent() returns Some("") (empty string), not None. The old code only handled None with unwrap_or_else, causing canonicalize() to fail. Add manifest_dir() helper that filters empty paths and use it consistently across build, add, and migrations commands.
1 parent 216d9d5 commit 5565f8d

4 files changed

Lines changed: 45 additions & 12 deletions

File tree

gnd/src/commands/add.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ pub async fn run_add(opt: AddOpt) -> Result<()> {
9494
let (abi, contract_name, start_block) = get_contract_info(&opt, &network).await?;
9595

9696
// Get project directory
97-
let project_dir = opt.manifest.parent().unwrap_or(Path::new("."));
97+
let project_dir = crate::manifest::manifest_dir(&opt.manifest);
9898

9999
// Create scaffold options for code generation
100100
let scaffold_options = ScaffoldOptions {

gnd/src/commands/build.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,7 @@ async fn build_subgraph(opt: &BuildOpt) -> Result<BuildResult> {
146146

147147
// Load the manifest
148148
let manifest = load_manifest(&opt.manifest)?;
149-
let source_dir = opt
150-
.manifest
151-
.parent()
152-
.filter(|p| !p.as_os_str().is_empty())
153-
.unwrap_or_else(|| Path::new("."))
154-
.to_path_buf();
149+
let source_dir = crate::manifest::manifest_dir(&opt.manifest).to_path_buf();
155150

156151
// Validate manifest structure
157152
let manifest_errors = validate_manifest(&manifest, &source_dir);

gnd/src/manifest.rs

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,19 +245,48 @@ fn parse_abis(abis_value: Option<&serde_json::Value>) -> Vec<Abi> {
245245
.unwrap_or_default()
246246
}
247247

248+
/// Get the directory containing a manifest file.
249+
///
250+
/// This handles the edge case where `manifest_path` is a bare filename
251+
/// like `"subgraph.yaml"` - in that case, `parent()` returns an empty
252+
/// path, so we fall back to `"."` (current directory).
253+
pub fn manifest_dir(manifest_path: &Path) -> &Path {
254+
manifest_path
255+
.parent()
256+
.filter(|p| !p.as_os_str().is_empty())
257+
.unwrap_or_else(|| Path::new("."))
258+
}
259+
248260
/// Resolve a path relative to the manifest file.
249261
pub fn resolve_path(manifest: &Path, path: &str) -> PathBuf {
250-
manifest
251-
.parent()
252-
.map(|p| p.join(path))
253-
.unwrap_or_else(|| PathBuf::from(path))
262+
manifest_dir(manifest).join(path)
254263
}
255264

256265
#[cfg(test)]
257266
mod tests {
258267
use super::*;
259268
use tempfile::TempDir;
260269

270+
#[test]
271+
fn test_manifest_dir_with_directory() {
272+
let manifest = PathBuf::from("/home/user/project/subgraph.yaml");
273+
assert_eq!(manifest_dir(&manifest), Path::new("/home/user/project"));
274+
}
275+
276+
#[test]
277+
fn test_manifest_dir_bare_filename() {
278+
// When manifest_path is just "subgraph.yaml", parent() returns Some("")
279+
// which is empty, so we should fall back to "."
280+
let manifest = PathBuf::from("subgraph.yaml");
281+
assert_eq!(manifest_dir(&manifest), Path::new("."));
282+
}
283+
284+
#[test]
285+
fn test_manifest_dir_relative_path() {
286+
let manifest = PathBuf::from("./subgraph.yaml");
287+
assert_eq!(manifest_dir(&manifest), Path::new("."));
288+
}
289+
261290
#[test]
262291
fn test_resolve_path() {
263292
let manifest = PathBuf::from("/home/user/project/subgraph.yaml");
@@ -266,6 +295,15 @@ mod tests {
266295
assert_eq!(resolved, PathBuf::from("/home/user/project/src/mapping.ts"));
267296
}
268297

298+
#[test]
299+
fn test_resolve_path_bare_filename() {
300+
// When manifest is just "subgraph.yaml", paths should resolve relative to "."
301+
let manifest = PathBuf::from("subgraph.yaml");
302+
let path = "src/mapping.ts";
303+
let resolved = resolve_path(&manifest, path);
304+
assert_eq!(resolved, PathBuf::from("./src/mapping.ts"));
305+
}
306+
269307
#[test]
270308
fn test_load_manifest_basic() {
271309
let temp_dir = TempDir::new().unwrap();

gnd/src/migrations/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ fn all_migrations() -> Vec<Box<dyn Migration>> {
7474
pub fn apply_migrations(manifest_path: &Path) -> Result<()> {
7575
step(Step::Load, "Apply migrations");
7676

77-
let source_dir = manifest_path.parent().unwrap_or_else(|| Path::new("."));
77+
let source_dir = crate::manifest::manifest_dir(manifest_path);
7878

7979
let ctx = MigrationContext {
8080
manifest_path,

0 commit comments

Comments
 (0)