@@ -32,7 +32,7 @@ mod hh;
3232pub use hh:: * ;
3333
3434use crate :: {
35- cache:: { CachedArtifact , CompilerCache } ,
35+ cache:: { CachedArtifacts , CompilerCache } ,
3636 output:: {
3737 contracts:: VersionedContracts ,
3838 sources:: { VersionedSourceFile , VersionedSourceFiles } ,
@@ -52,6 +52,7 @@ pub struct ArtifactId {
5252 pub version : Version ,
5353 /// `solc` build id
5454 pub build_id : String ,
55+ pub profile : String ,
5556}
5657
5758impl ArtifactId {
@@ -119,6 +120,7 @@ pub struct ArtifactFile<T> {
119120 /// `solc` version that produced this artifact
120121 pub version : Version ,
121122 pub build_id : String ,
123+ pub profile : String ,
122124}
123125
124126impl < T : Serialize > ArtifactFile < T > {
@@ -298,6 +300,7 @@ impl<T> Artifacts<T> {
298300 source : source. clone ( ) ,
299301 version : artifact. version . clone ( ) ,
300302 build_id : artifact. build_id . clone ( ) ,
303+ profile : artifact. profile . clone ( ) ,
301304 }
302305 . with_slashed_paths ( ) ,
303306 & artifact. artifact ,
@@ -324,6 +327,7 @@ impl<T> Artifacts<T> {
324327 source : source. clone ( ) ,
325328 version : artifact. version ,
326329 build_id : artifact. build_id . clone ( ) ,
330+ profile : artifact. profile . clone ( ) ,
327331 }
328332 . with_slashed_paths ( ) ,
329333 artifact. artifact ,
@@ -643,14 +647,22 @@ pub trait ArtifactOutput {
643647
644648 /// Returns the file name for the contract's artifact
645649 /// `Greeter.json`
646- fn output_file_name ( name : & str ) -> PathBuf {
647- format ! ( "{name}.json" ) . into ( )
648- }
649-
650- /// Returns the file name for the contract's artifact and the given version
651- /// `Greeter.0.8.11.json`
652- fn output_file_name_versioned ( name : & str , version : & Version ) -> PathBuf {
653- format ! ( "{}.{}.{}.{}.json" , name, version. major, version. minor, version. patch) . into ( )
650+ fn output_file_name (
651+ name : & str ,
652+ version : & Version ,
653+ profile : & str ,
654+ with_version : bool ,
655+ with_profile : bool ,
656+ ) -> PathBuf {
657+ let mut name = name. to_string ( ) ;
658+ if with_version {
659+ name. push_str ( & format ! ( ".{}.{}.{}" , version. major, version. minor, version. patch) ) ;
660+ }
661+ if with_profile {
662+ name. push_str ( & format ! ( ".{profile}" ) ) ;
663+ }
664+ name. push_str ( ".json" ) ;
665+ name. into ( )
654666 }
655667
656668 /// Returns the appropriate file name for the conflicting file.
@@ -725,24 +737,23 @@ pub trait ArtifactOutput {
725737 /// Returns the path to the contract's artifact location based on the contract's file and name
726738 ///
727739 /// This returns `contract.sol/contract.json` by default
728- fn output_file ( contract_file : & Path , name : & str ) -> PathBuf {
729- contract_file
730- . file_name ( )
731- . map ( Path :: new)
732- . map ( |p| p. join ( Self :: output_file_name ( name) ) )
733- . unwrap_or_else ( || Self :: output_file_name ( name) )
734- }
735-
736- /// Returns the path to the contract's artifact location based on the contract's file, name and
737- /// version
738- ///
739- /// This returns `contract.sol/contract.0.8.11.json` by default
740- fn output_file_versioned ( contract_file : & Path , name : & str , version : & Version ) -> PathBuf {
740+ fn output_file (
741+ contract_file : & Path ,
742+ name : & str ,
743+ version : & Version ,
744+ profile : & str ,
745+ with_version : bool ,
746+ with_profile : bool ,
747+ ) -> PathBuf {
741748 contract_file
742749 . file_name ( )
743750 . map ( Path :: new)
744- . map ( |p| p. join ( Self :: output_file_name_versioned ( name, version) ) )
745- . unwrap_or_else ( || Self :: output_file_name_versioned ( name, version) )
751+ . map ( |p| {
752+ p. join ( Self :: output_file_name ( name, version, profile, with_version, with_profile) )
753+ } )
754+ . unwrap_or_else ( || {
755+ Self :: output_file_name ( name, version, profile, with_version, with_profile)
756+ } )
746757 }
747758
748759 /// The inverse of `contract_file_name`
@@ -753,11 +764,6 @@ pub trait ArtifactOutput {
753764 file. file_stem ( ) . and_then ( |s| s. to_str ( ) . map ( |s| s. to_string ( ) ) )
754765 }
755766
756- /// Whether the corresponding artifact of the given contract file and name exists
757- fn output_exists ( contract_file : & Path , name : & str , root : & Path ) -> bool {
758- root. join ( Self :: output_file ( contract_file, name) ) . exists ( )
759- }
760-
761767 /// Read the artifact that's stored at the given path
762768 ///
763769 /// # Errors
@@ -801,28 +807,27 @@ pub trait ArtifactOutput {
801807
802808 /// Generates a path for an artifact based on already taken paths by either cached or compiled
803809 /// artifacts.
810+ #[ allow( clippy:: too_many_arguments) ]
804811 fn get_artifact_path (
805812 ctx : & OutputContext < ' _ > ,
806813 already_taken : & HashSet < String > ,
807814 file : & Path ,
808815 name : & str ,
809816 artifacts_folder : & Path ,
810817 version : & Version ,
811- versioned : bool ,
818+ profile : & str ,
819+ with_version : bool ,
820+ with_profile : bool ,
812821 ) -> PathBuf {
813822 // if an artifact for the contract already exists (from a previous compile job)
814823 // we reuse the path, this will make sure that even if there are conflicting
815824 // files (files for witch `T::output_file()` would return the same path) we use
816825 // consistent output paths
817- if let Some ( existing_artifact) = ctx. existing_artifact ( file, name, version) {
826+ if let Some ( existing_artifact) = ctx. existing_artifact ( file, name, version, profile ) {
818827 trace ! ( "use existing artifact file {:?}" , existing_artifact, ) ;
819828 existing_artifact. to_path_buf ( )
820829 } else {
821- let path = if versioned {
822- Self :: output_file_versioned ( file, name, version)
823- } else {
824- Self :: output_file ( file, name)
825- } ;
830+ let path = Self :: output_file ( file, name, version, profile, with_version, with_profile) ;
826831
827832 let path = artifacts_folder. join ( path) ;
828833
@@ -855,7 +860,9 @@ pub trait ArtifactOutput {
855860 let mut taken_paths_lowercase = ctx
856861 . existing_artifacts
857862 . values ( )
858- . flat_map ( |artifacts| artifacts. values ( ) . flat_map ( |artifacts| artifacts. values ( ) ) )
863+ . flat_map ( |artifacts| artifacts. values ( ) )
864+ . flat_map ( |artifacts| artifacts. values ( ) )
865+ . flat_map ( |artifacts| artifacts. values ( ) )
859866 . map ( |a| a. path . to_slash_lossy ( ) . to_lowercase ( ) )
860867 . collect :: < HashSet < _ > > ( ) ;
861868
@@ -866,22 +873,26 @@ pub trait ArtifactOutput {
866873 } ) ;
867874 for file in files {
868875 for ( name, versioned_contracts) in & contracts[ file] {
876+ let unique_versions =
877+ versioned_contracts. iter ( ) . map ( |c| & c. version ) . collect :: < HashSet < _ > > ( ) ;
878+ let unique_profiles =
879+ versioned_contracts. iter ( ) . map ( |c| & c. profile ) . collect :: < HashSet < _ > > ( ) ;
869880 for contract in versioned_contracts {
881+ non_standalone_sources. insert ( file) ;
882+
870883 // track `SourceFile`s that can be mapped to contracts
871884 let source_file = sources. find_file_and_version ( file, & contract. version ) ;
872885
873- if let Some ( source) = source_file {
874- non_standalone_sources. insert ( ( source. id , & contract. version ) ) ;
875- }
876-
877886 let artifact_path = Self :: get_artifact_path (
878887 & ctx,
879888 & taken_paths_lowercase,
880889 file,
881890 name,
882891 layout. artifacts . as_path ( ) ,
883892 & contract. version ,
884- versioned_contracts. len ( ) > 1 ,
893+ & contract. profile ,
894+ unique_versions. len ( ) > 1 ,
895+ unique_profiles. len ( ) > 1 ,
885896 ) ;
886897
887898 taken_paths_lowercase. insert ( artifact_path. to_slash_lossy ( ) . to_lowercase ( ) ) ;
@@ -905,6 +916,7 @@ pub trait ArtifactOutput {
905916 file : artifact_path,
906917 version : contract. version . clone ( ) ,
907918 build_id : contract. build_id . clone ( ) ,
919+ profile : contract. profile . clone ( ) ,
908920 } ;
909921
910922 artifacts
@@ -922,8 +934,10 @@ pub trait ArtifactOutput {
922934 // any contract definition, which are not included in the `CompilerOutput` but we want to
923935 // create Artifacts for them regardless
924936 for ( file, sources) in sources. as_ref ( ) . iter ( ) {
937+ let unique_versions = sources. iter ( ) . map ( |s| & s. version ) . collect :: < HashSet < _ > > ( ) ;
938+ let unique_profiles = sources. iter ( ) . map ( |s| & s. profile ) . collect :: < HashSet < _ > > ( ) ;
925939 for source in sources {
926- if !non_standalone_sources. contains ( & ( source . source_file . id , & source . version ) ) {
940+ if !non_standalone_sources. contains ( file ) {
927941 // scan the ast as a safe measure to ensure this file does not include any
928942 // source units
929943 // there's also no need to create a standalone artifact for source files that
@@ -946,26 +960,26 @@ pub trait ArtifactOutput {
946960 name,
947961 & layout. artifacts ,
948962 & source. version ,
949- sources. len ( ) > 1 ,
963+ & source. profile ,
964+ unique_versions. len ( ) > 1 ,
965+ unique_profiles. len ( ) > 1 ,
950966 ) ;
951967
952- let entries = artifacts
968+ taken_paths_lowercase
969+ . insert ( artifact_path. to_slash_lossy ( ) . to_lowercase ( ) ) ;
970+
971+ artifacts
953972 . entry ( file. clone ( ) )
954973 . or_default ( )
955974 . entry ( name. to_string ( ) )
956- . or_default ( ) ;
957-
958- if entries. iter ( ) . all ( |entry| entry. version != source. version ) {
959- taken_paths_lowercase
960- . insert ( artifact_path. to_slash_lossy ( ) . to_lowercase ( ) ) ;
961-
962- entries. push ( ArtifactFile {
975+ . or_default ( )
976+ . push ( ArtifactFile {
963977 artifact,
964978 file : artifact_path,
965979 version : source. version . clone ( ) ,
966980 build_id : source. build_id . clone ( ) ,
981+ profile : source. profile . clone ( ) ,
967982 } ) ;
968- }
969983 }
970984 }
971985 }
@@ -1016,8 +1030,7 @@ pub struct OutputContext<'a> {
10161030 /// └── inner
10171031 /// └── a.sol
10181032 /// ```
1019- pub existing_artifacts :
1020- BTreeMap < & ' a Path , & ' a BTreeMap < String , BTreeMap < Version , CachedArtifact > > > ,
1033+ pub existing_artifacts : BTreeMap < & ' a Path , & ' a CachedArtifacts > ,
10211034}
10221035
10231036// === impl OutputContext
@@ -1043,13 +1056,14 @@ impl<'a> OutputContext<'a> {
10431056 file : & Path ,
10441057 contract : & str ,
10451058 version : & Version ,
1059+ profile : & str ,
10461060 ) -> Option < & Path > {
1047- self . existing_artifacts . get ( file ) . and_then ( |contracts| {
1048- contracts
1049- . get ( contract)
1050- . and_then ( |versions| versions. get ( version) )
1051- . map ( |a| a . path . as_path ( ) )
1052- } )
1061+ self . existing_artifacts
1062+ . get ( file )
1063+ . and_then ( |contracts| contracts . get ( contract) )
1064+ . and_then ( |versions| versions. get ( version) )
1065+ . and_then ( |profiles| profiles . get ( profile ) )
1066+ . map ( |a| a . path . as_path ( ) )
10531067 }
10541068}
10551069
0 commit comments