Skip to content

Commit ca2b54d

Browse files
committed
fix: allow single sol file remappings
1 parent 910af38 commit ca2b54d

File tree

2 files changed

+67
-7
lines changed

2 files changed

+67
-7
lines changed

crates/artifacts/solc/src/remappings/mod.rs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,11 @@ impl fmt::Display for Remapping {
138138
}
139139
s.push(':');
140140
}
141-
let name =
142-
if !self.name.ends_with('/') { format!("{}/", self.name) } else { self.name.clone() };
141+
let name = if !self.name.ends_with('/') && !self.name.ends_with(".sol") {
142+
format!("{}/", self.name)
143+
} else {
144+
self.name.clone()
145+
};
143146
s.push_str(&{
144147
#[cfg(target_os = "windows")]
145148
{
@@ -153,7 +156,7 @@ impl fmt::Display for Remapping {
153156
}
154157
});
155158

156-
if !s.ends_with('/') {
159+
if !s.ends_with('/') && !s.ends_with(".sol") {
157160
s.push('/');
158161
}
159162
f.write_str(&s)
@@ -241,7 +244,7 @@ impl fmt::Display for RelativeRemapping {
241244
}
242245
});
243246

244-
if !s.ends_with('/') {
247+
if !s.ends_with('/') && !s.ends_with(".sol") {
245248
s.push('/');
246249
}
247250
f.write_str(&s)
@@ -252,10 +255,10 @@ impl From<RelativeRemapping> for Remapping {
252255
fn from(r: RelativeRemapping) -> Self {
253256
let RelativeRemapping { context, mut name, path } = r;
254257
let mut path = path.relative().display().to_string();
255-
if !path.ends_with('/') {
258+
if !path.ends_with('/') && !path.ends_with(".sol") {
256259
path.push('/');
257260
}
258-
if !name.ends_with('/') {
261+
if !name.ends_with('/') && !name.ends_with(".sol") {
259262
name.push('/');
260263
}
261264
Self { context, name, path }
@@ -423,4 +426,21 @@ mod tests {
423426
);
424427
assert_eq!(remapping.to_string(), "oz/=a/b/c/d/".to_string());
425428
}
429+
430+
// <https://github.com/foundry-rs/foundry/issues/6706#issuecomment-3141270852>
431+
#[test]
432+
fn can_preserve_single_sol_file_remapping() {
433+
let remapping = "@my-lib/B.sol=lib/my-lib/B.sol";
434+
let remapping = Remapping::from_str(remapping).unwrap();
435+
436+
assert_eq!(
437+
remapping,
438+
Remapping {
439+
context: None,
440+
name: "@my-lib/B.sol".to_string(),
441+
path: "lib/my-lib/B.sol".to_string()
442+
}
443+
);
444+
assert_eq!(remapping.to_string(), "@my-lib/B.sol=lib/my-lib/B.sol".to_string());
445+
}
426446
}

crates/compilers/src/config.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,12 @@ impl<L> ProjectPathsConfig<L> {
524524
})
525525
.find_map(|r| {
526526
import.strip_prefix(&r.name).ok().map(|stripped_import| {
527-
let lib_path = Path::new(&r.path).join(stripped_import);
527+
let lib_path =
528+
if stripped_import.as_os_str().is_empty() && r.path.ends_with(".sol") {
529+
r.path.clone().into()
530+
} else {
531+
Path::new(&r.path).join(stripped_import)
532+
};
528533

529534
// we handle the edge case where the path of a remapping ends with "contracts"
530535
// (`<name>/=.../contracts`) and the stripped import also starts with
@@ -1196,4 +1201,39 @@ mod tests {
11961201
dependency.join("A.sol")
11971202
);
11981203
}
1204+
1205+
#[test]
1206+
fn can_resolve_single_file_mapped_import() {
1207+
let dir = tempfile::tempdir().unwrap();
1208+
let mut config = ProjectPathsConfig::builder().root(dir.path()).build::<()>().unwrap();
1209+
config.create_all().unwrap();
1210+
1211+
fs::write(
1212+
config.sources.join("A.sol"),
1213+
r#"pragma solidity ^0.8.0; import "@my-lib/B.sol"; contract A is B {}"#,
1214+
)
1215+
.unwrap();
1216+
1217+
let dependency = config.root.join("my-lib");
1218+
fs::create_dir(&dependency).unwrap();
1219+
fs::write(dependency.join("B.sol"), r"pragma solidity ^0.8.0; contract B {}").unwrap();
1220+
1221+
config.remappings.push(Remapping {
1222+
context: None,
1223+
name: "@my-lib/B.sol".into(),
1224+
path: "my-lib/B.sol".into(),
1225+
});
1226+
1227+
// Test that single file import / remapping resolves to file.
1228+
assert!(config
1229+
.resolve_import_and_include_paths(
1230+
&config.sources,
1231+
Path::new("@my-lib/B.sol"),
1232+
&mut Default::default(),
1233+
)
1234+
.unwrap()
1235+
.to_str()
1236+
.unwrap()
1237+
.ends_with("my-lib/B.sol"));
1238+
}
11991239
}

0 commit comments

Comments
 (0)