feat(solc): add helper functions to compile standalone files (#931)

This commit is contained in:
Matthias Seitz 2022-02-19 14:56:34 +01:00 committed by GitHub
parent d050bc7081
commit 3effda2804
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 88 additions and 1 deletions

View File

@ -235,6 +235,49 @@ impl<T: ArtifactOutput> Project<T> {
project::ProjectCompiler::with_sources(self, sources)?.compile() project::ProjectCompiler::with_sources(self, sources)?.compile()
} }
/// Convenience function to compile a single solidity file with the project's settings.
/// Same as [`Self::svm_compile()`] but with the given `file` as input.
///
/// # Example
///
/// ```
/// use ethers_solc::Project;
/// # fn demo(project: Project) {
/// let project = Project::builder().build().unwrap();
/// let output = project.compile_file("example/Greeter.sol").unwrap();
/// # }
/// ```
#[cfg(all(feature = "svm", feature = "async"))]
pub fn compile_file(&self, file: impl Into<PathBuf>) -> Result<ProjectCompileOutput<T>> {
let file = file.into();
let source = Source::read(&file)?;
project::ProjectCompiler::with_sources(self, Sources::from([(file, source)]))?.compile()
}
/// Convenience function to compile a series of solidity files with the project's settings.
/// Same as [`Self::svm_compile()`] but with the given `files` as input.
///
/// # Example
///
/// ```
/// use ethers_solc::Project;
/// # fn demo(project: Project) {
/// let project = Project::builder().build().unwrap();
/// let output = project
/// .compile_files(
/// vec!["examples/Foo.sol", "examples/Bar.sol"]
/// ).unwrap();
/// # }
/// ```
#[cfg(all(feature = "svm", feature = "async"))]
pub fn compile_files<P, I>(&self, files: I) -> Result<ProjectCompileOutput<T>>
where
I: IntoIterator<Item = P>,
P: Into<PathBuf>,
{
project::ProjectCompiler::with_sources(self, Source::read_all(files)?)?.compile()
}
/// Compiles the given source files with the exact `Solc` executable /// Compiles the given source files with the exact `Solc` executable
/// ///
/// First all libraries for the sources are resolved by scanning all their imports. /// First all libraries for the sources are resolved by scanning all their imports.

View File

@ -154,12 +154,20 @@ impl<T: ArtifactOutput> TempProject<T> {
create_contract_file(lib, content) create_contract_file(lib, content)
} }
/// Adds a new source file /// Adds a new source file inside the project's source dir
pub fn add_source(&self, name: impl AsRef<str>, content: impl AsRef<str>) -> Result<PathBuf> { pub fn add_source(&self, name: impl AsRef<str>, content: impl AsRef<str>) -> Result<PathBuf> {
let name = contract_file_name(name); let name = contract_file_name(name);
let source = self.paths().sources.join(name); let source = self.paths().sources.join(name);
create_contract_file(source, content) create_contract_file(source, content)
} }
/// Adds a solidity contract in the project's root dir.
/// This will also create all intermediary dirs.
pub fn add_contract(&self, name: impl AsRef<str>, content: impl AsRef<str>) -> Result<PathBuf> {
let name = contract_file_name(name);
let source = self.root().join(name);
create_contract_file(source, content)
}
} }
impl<T: ArtifactOutput + Default> TempProject<T> { impl<T: ArtifactOutput + Default> TempProject<T> {

View File

@ -454,3 +454,39 @@ fn can_detect_type_error() {
let compiled = project.compile().unwrap(); let compiled = project.compile().unwrap();
assert!(compiled.has_compiler_errors()); assert!(compiled.has_compiler_errors());
} }
#[test]
fn can_compile_single_files() {
let tmp = TempProject::dapptools().unwrap();
let foo = tmp
.add_contract(
"examples/Foo",
r#"
pragma solidity ^0.8.10;
contract Foo {}
"#,
)
.unwrap();
let compiled = tmp.project().compile_file(foo.clone()).unwrap();
assert!(!compiled.has_compiler_errors());
assert!(compiled.find("Foo").is_some());
let bar = tmp
.add_contract(
"examples/Bar",
r#"
pragma solidity ^0.8.10;
contract Bar {}
"#,
)
.unwrap();
let compiled = tmp.project().compile_files(vec![foo, bar]).unwrap();
assert!(!compiled.has_compiler_errors());
assert!(compiled.find("Foo").is_some());
assert!(compiled.find("Bar").is_some());
}