Skip to content

Commit a9098d0

Browse files
committed
wip
1 parent 56a31ee commit a9098d0

File tree

10 files changed

+248
-148
lines changed

10 files changed

+248
-148
lines changed

crates/compilers/src/artifact_output/mod.rs

Lines changed: 64 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ pub struct ArtifactFile<T> {
119119
/// `solc` version that produced this artifact
120120
pub version: Version,
121121
pub build_id: String,
122+
pub profile: String,
122123
}
123124

124125
impl<T: Serialize> ArtifactFile<T> {
@@ -642,14 +643,22 @@ pub trait ArtifactOutput {
642643

643644
/// Returns the file name for the contract's artifact
644645
/// `Greeter.json`
645-
fn output_file_name(name: &str) -> PathBuf {
646-
format!("{name}.json").into()
647-
}
648-
649-
/// Returns the file name for the contract's artifact and the given version
650-
/// `Greeter.0.8.11.json`
651-
fn output_file_name_versioned(name: &str, version: &Version) -> PathBuf {
652-
format!("{}.{}.{}.{}.json", name, version.major, version.minor, version.patch).into()
646+
fn output_file_name(
647+
name: &str,
648+
version: &Version,
649+
profile: &str,
650+
with_version: bool,
651+
with_profile: bool,
652+
) -> PathBuf {
653+
let mut name = name.to_string();
654+
if with_version {
655+
name.push_str(&format!(".{}.{}.{}", version.major, version.minor, version.patch));
656+
}
657+
if with_profile {
658+
name.push_str(&format!(".{}", profile));
659+
}
660+
name.push_str(".json");
661+
name.into()
653662
}
654663

655664
/// Returns the appropriate file name for the conflicting file.
@@ -724,24 +733,23 @@ pub trait ArtifactOutput {
724733
/// Returns the path to the contract's artifact location based on the contract's file and name
725734
///
726735
/// This returns `contract.sol/contract.json` by default
727-
fn output_file(contract_file: &Path, name: &str) -> PathBuf {
728-
contract_file
729-
.file_name()
730-
.map(Path::new)
731-
.map(|p| p.join(Self::output_file_name(name)))
732-
.unwrap_or_else(|| Self::output_file_name(name))
733-
}
734-
735-
/// Returns the path to the contract's artifact location based on the contract's file, name and
736-
/// version
737-
///
738-
/// This returns `contract.sol/contract.0.8.11.json` by default
739-
fn output_file_versioned(contract_file: &Path, name: &str, version: &Version) -> PathBuf {
736+
fn output_file(
737+
contract_file: &Path,
738+
name: &str,
739+
version: &Version,
740+
profile: &str,
741+
with_version: bool,
742+
with_profile: bool,
743+
) -> PathBuf {
740744
contract_file
741745
.file_name()
742746
.map(Path::new)
743-
.map(|p| p.join(Self::output_file_name_versioned(name, version)))
744-
.unwrap_or_else(|| Self::output_file_name_versioned(name, version))
747+
.map(|p| {
748+
p.join(Self::output_file_name(name, version, profile, with_version, with_profile))
749+
})
750+
.unwrap_or_else(|| {
751+
Self::output_file_name(name, version, profile, with_version, with_profile)
752+
})
745753
}
746754

747755
/// The inverse of `contract_file_name`
@@ -752,11 +760,6 @@ pub trait ArtifactOutput {
752760
file.file_stem().and_then(|s| s.to_str().map(|s| s.to_string()))
753761
}
754762

755-
/// Whether the corresponding artifact of the given contract file and name exists
756-
fn output_exists(contract_file: &Path, name: &str, root: &Path) -> bool {
757-
root.join(Self::output_file(contract_file, name)).exists()
758-
}
759-
760763
/// Read the artifact that's stored at the given path
761764
///
762765
/// # Errors
@@ -807,21 +810,19 @@ pub trait ArtifactOutput {
807810
name: &str,
808811
artifacts_folder: &Path,
809812
version: &Version,
810-
versioned: bool,
813+
profile: &str,
814+
with_version: bool,
815+
with_profile: bool,
811816
) -> PathBuf {
812817
// if an artifact for the contract already exists (from a previous compile job)
813818
// we reuse the path, this will make sure that even if there are conflicting
814819
// files (files for witch `T::output_file()` would return the same path) we use
815820
// consistent output paths
816-
if let Some(existing_artifact) = ctx.existing_artifact(file, name, version) {
821+
if let Some(existing_artifact) = ctx.existing_artifact(file, name, version, profile) {
817822
trace!("use existing artifact file {:?}", existing_artifact,);
818823
existing_artifact.to_path_buf()
819824
} else {
820-
let path = if versioned {
821-
Self::output_file_versioned(file, name, version)
822-
} else {
823-
Self::output_file(file, name)
824-
};
825+
let path = Self::output_file(file, name, version, profile, with_version, with_profile);
825826

826827
let path = artifacts_folder.join(path);
827828

@@ -854,7 +855,9 @@ pub trait ArtifactOutput {
854855
let mut taken_paths_lowercase = ctx
855856
.existing_artifacts
856857
.values()
857-
.flat_map(|artifacts| artifacts.values().flat_map(|artifacts| artifacts.values()))
858+
.flat_map(|artifacts| artifacts.values())
859+
.flat_map(|artifacts| artifacts.values())
860+
.flat_map(|artifacts| artifacts.values())
858861
.map(|a| a.path.to_slash_lossy().to_lowercase())
859862
.collect::<HashSet<_>>();
860863

@@ -865,6 +868,10 @@ pub trait ArtifactOutput {
865868
});
866869
for file in files {
867870
for (name, versioned_contracts) in &contracts[file] {
871+
let unique_versions =
872+
versioned_contracts.iter().map(|c| &c.version).collect::<HashSet<_>>();
873+
let unique_profiles =
874+
versioned_contracts.iter().map(|c| &c.profile).collect::<HashSet<_>>();
868875
for contract in versioned_contracts {
869876
// track `SourceFile`s that can be mapped to contracts
870877
let source_file = sources.find_file_and_version(file, &contract.version);
@@ -880,7 +887,9 @@ pub trait ArtifactOutput {
880887
name,
881888
layout.artifacts.as_path(),
882889
&contract.version,
883-
versioned_contracts.len() > 1,
890+
&contract.profile,
891+
unique_versions.len() > 1,
892+
unique_profiles.len() > 1,
884893
);
885894

886895
taken_paths_lowercase.insert(artifact_path.to_slash_lossy().to_lowercase());
@@ -904,6 +913,7 @@ pub trait ArtifactOutput {
904913
file: artifact_path,
905914
version: contract.version.clone(),
906915
build_id: contract.build_id.clone(),
916+
profile: contract.profile.clone(),
907917
};
908918

909919
artifacts
@@ -921,6 +931,8 @@ pub trait ArtifactOutput {
921931
// any contract definition, which are not included in the `CompilerOutput` but we want to
922932
// create Artifacts for them regardless
923933
for (file, sources) in sources.as_ref().iter() {
934+
let unique_versions = sources.iter().map(|s| &s.version).collect::<HashSet<_>>();
935+
let unique_profiles = sources.iter().map(|s| &s.profile).collect::<HashSet<_>>();
924936
for source in sources {
925937
if !non_standalone_sources.contains(&(source.source_file.id, &source.version)) {
926938
// scan the ast as a safe measure to ensure this file does not include any
@@ -945,7 +957,9 @@ pub trait ArtifactOutput {
945957
name,
946958
&layout.artifacts,
947959
&source.version,
948-
sources.len() > 1,
960+
&source.profile,
961+
unique_versions.len() > 1,
962+
unique_profiles.len() > 1,
949963
);
950964

951965
let entries = artifacts
@@ -963,6 +977,7 @@ pub trait ArtifactOutput {
963977
file: artifact_path,
964978
version: source.version.clone(),
965979
build_id: source.build_id.clone(),
980+
profile: source.profile.clone(),
966981
});
967982
}
968983
}
@@ -1015,8 +1030,10 @@ pub struct OutputContext<'a> {
10151030
/// └── inner
10161031
/// └── a.sol
10171032
/// ```
1018-
pub existing_artifacts:
1019-
BTreeMap<&'a Path, &'a BTreeMap<String, BTreeMap<Version, CachedArtifact>>>,
1033+
pub existing_artifacts: BTreeMap<
1034+
&'a Path,
1035+
&'a BTreeMap<String, BTreeMap<Version, BTreeMap<String, CachedArtifact>>>,
1036+
>,
10201037
}
10211038

10221039
// === impl OutputContext
@@ -1042,13 +1059,14 @@ impl<'a> OutputContext<'a> {
10421059
file: &Path,
10431060
contract: &str,
10441061
version: &Version,
1062+
profile: &str,
10451063
) -> Option<&Path> {
1046-
self.existing_artifacts.get(file).and_then(|contracts| {
1047-
contracts
1048-
.get(contract)
1049-
.and_then(|versions| versions.get(version))
1050-
.map(|a| a.path.as_path())
1051-
})
1064+
self.existing_artifacts
1065+
.get(file)
1066+
.and_then(|contracts| contracts.get(contract))
1067+
.and_then(|versions| versions.get(version))
1068+
.and_then(|profiles| profiles.get(profile))
1069+
.map(|a| a.path.as_path())
10521070
}
10531071
}
10541072

0 commit comments

Comments
 (0)