Skip to content

Commit 6b0eb6e

Browse files
authored
feat(forge-inspect): add ability to inspect libraries (#11732)
1 parent d8be07b commit 6b0eb6e

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

crates/forge/src/cmd/inspect.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,27 @@ impl InspectArgs {
148148
};
149149
print_json(&standard_json)?;
150150
}
151+
ContractArtifactField::Libraries => {
152+
let all_libs: Vec<String> = artifact
153+
.all_link_references()
154+
.into_iter()
155+
.flat_map(|(path, libs)| {
156+
libs.into_keys().map(move |lib| format!("{path}:{lib}"))
157+
})
158+
.collect();
159+
if shell::is_json() {
160+
return print_json(&all_libs);
161+
} else {
162+
sh_println!(
163+
"Dynamically linked libraries:\n{}",
164+
all_libs
165+
.iter()
166+
.map(|v| format!(" {v}"))
167+
.collect::<Vec<String>>()
168+
.join("\n")
169+
)?;
170+
}
171+
}
151172
};
152173

153174
Ok(())
@@ -406,6 +427,7 @@ pub enum ContractArtifactField {
406427
Errors,
407428
Events,
408429
StandardJson,
430+
Libraries,
409431
}
410432

411433
macro_rules! impl_value_enum {
@@ -489,6 +511,7 @@ impl_value_enum! {
489511
Errors => "errors" | "er",
490512
Events => "events" | "ev",
491513
StandardJson => "standardJson" | "standard-json" | "standard_json",
514+
Libraries => "libraries" | "lib" | "libs",
492515
}
493516
}
494517

@@ -521,6 +544,7 @@ impl TryFrom<ContractArtifactField> for ContractOutputSelection {
521544
Caf::StandardJson => {
522545
Err(eyre!("StandardJson is not supported for ContractOutputSelection"))
523546
}
547+
Caf::Libraries => Err(eyre!("Libraries is not supported for ContractOutputSelection")),
524548
}
525549
}
526550
}
@@ -559,7 +583,10 @@ impl fmt::Display for ContractArtifactField {
559583
impl ContractArtifactField {
560584
/// Returns true if this field does not need to be passed to the compiler.
561585
pub const fn can_skip_field(&self) -> bool {
562-
matches!(self, Self::Bytecode | Self::DeployedBytecode | Self::StandardJson)
586+
matches!(
587+
self,
588+
Self::Bytecode | Self::DeployedBytecode | Self::StandardJson | Self::Libraries
589+
)
563590
}
564591
}
565592

@@ -627,6 +654,14 @@ mod tests {
627654
.to_string()
628655
.eq("StandardJson is not supported for ContractOutputSelection")
629656
);
657+
} else if field == ContractArtifactField::Libraries {
658+
let selection: Result<ContractOutputSelection, _> = field.try_into();
659+
assert!(
660+
selection
661+
.unwrap_err()
662+
.to_string()
663+
.eq("Libraries is not supported for ContractOutputSelection")
664+
);
630665
} else {
631666
let selection: ContractOutputSelection = field.try_into().unwrap();
632667
assert_eq!(field, selection);

crates/forge/tests/cli/cmd.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3767,6 +3767,41 @@ forgetest_init!(can_inspect_standard_json, |prj, cmd| {
37673767
"#]]);
37683768
});
37693769

3770+
forgetest_init!(can_inspect_libraries, |prj, cmd| {
3771+
prj.add_source(
3772+
"Source.sol",
3773+
r#"
3774+
import "./Lib.sol";
3775+
3776+
library Lib2 {
3777+
function foo() public {}
3778+
}
3779+
3780+
contract Source {
3781+
function foo() public {
3782+
Lib.foo();
3783+
Lib2.foo();
3784+
}
3785+
}"#,
3786+
);
3787+
3788+
prj.add_source(
3789+
"Lib.sol",
3790+
r#"
3791+
library Lib {
3792+
function foo() public {}
3793+
}
3794+
"#,
3795+
);
3796+
3797+
cmd.args(["inspect", "Source", "libraries"]).assert_success().stdout_eq(str![[r#"
3798+
Dynamically linked libraries:
3799+
src/Lib.sol:Lib
3800+
src/Source.sol:Lib2
3801+
3802+
"#]]);
3803+
});
3804+
37703805
// checks that `clean` also works with the "out" value set in Config
37713806
forgetest_init!(gas_report_include_tests, |prj, cmd| {
37723807
prj.update_config(|config| {

0 commit comments

Comments
 (0)