@@ -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 ,
@@ -642,14 +646,22 @@ pub trait ArtifactOutput {
642646
643647 /// Returns the file name for the contract's artifact
644648 /// `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 ( )
649+ fn output_file_name (
650+ name : & str ,
651+ version : & Version ,
652+ profile : & str ,
653+ with_version : bool ,
654+ with_profile : bool ,
655+ ) -> PathBuf {
656+ let mut name = name. to_string ( ) ;
657+ if with_version {
658+ name. push_str ( & format ! ( ".{}.{}.{}" , version. major, version. minor, version. patch) ) ;
659+ }
660+ if with_profile {
661+ name. push_str ( & format ! ( ".{profile}" ) ) ;
662+ }
663+ name. push_str ( ".json" ) ;
664+ name. into ( )
653665 }
654666
655667 /// Returns the appropriate file name for the conflicting file.
@@ -724,24 +736,23 @@ pub trait ArtifactOutput {
724736 /// Returns the path to the contract's artifact location based on the contract's file and name
725737 ///
726738 /// 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 {
739+ fn output_file (
740+ contract_file : & Path ,
741+ name : & str ,
742+ version : & Version ,
743+ profile : & str ,
744+ with_version : bool ,
745+ with_profile : bool ,
746+ ) -> PathBuf {
740747 contract_file
741748 . file_name ( )
742749 . 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) )
750+ . map ( |p| {
751+ p. join ( Self :: output_file_name ( name, version, profile, with_version, with_profile) )
752+ } )
753+ . unwrap_or_else ( || {
754+ Self :: output_file_name ( name, version, profile, with_version, with_profile)
755+ } )
745756 }
746757
747758 /// The inverse of `contract_file_name`
@@ -752,11 +763,6 @@ pub trait ArtifactOutput {
752763 file. file_stem ( ) . and_then ( |s| s. to_str ( ) . map ( |s| s. to_string ( ) ) )
753764 }
754765
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-
760766 /// Read the artifact that's stored at the given path
761767 ///
762768 /// # Errors
@@ -800,28 +806,27 @@ pub trait ArtifactOutput {
800806
801807 /// Generates a path for an artifact based on already taken paths by either cached or compiled
802808 /// artifacts.
809+ #[ allow( clippy:: too_many_arguments) ]
803810 fn get_artifact_path (
804811 ctx : & OutputContext < ' _ > ,
805812 already_taken : & HashSet < String > ,
806813 file : & Path ,
807814 name : & str ,
808815 artifacts_folder : & Path ,
809816 version : & Version ,
810- versioned : bool ,
817+ profile : & str ,
818+ with_version : bool ,
819+ with_profile : bool ,
811820 ) -> PathBuf {
812821 // if an artifact for the contract already exists (from a previous compile job)
813822 // we reuse the path, this will make sure that even if there are conflicting
814823 // files (files for witch `T::output_file()` would return the same path) we use
815824 // consistent output paths
816- if let Some ( existing_artifact) = ctx. existing_artifact ( file, name, version) {
825+ if let Some ( existing_artifact) = ctx. existing_artifact ( file, name, version, profile ) {
817826 trace ! ( "use existing artifact file {:?}" , existing_artifact, ) ;
818827 existing_artifact. to_path_buf ( )
819828 } else {
820- let path = if versioned {
821- Self :: output_file_versioned ( file, name, version)
822- } else {
823- Self :: output_file ( file, name)
824- } ;
829+ let path = Self :: output_file ( file, name, version, profile, with_version, with_profile) ;
825830
826831 let path = artifacts_folder. join ( path) ;
827832
@@ -854,7 +859,9 @@ pub trait ArtifactOutput {
854859 let mut taken_paths_lowercase = ctx
855860 . existing_artifacts
856861 . values ( )
857- . flat_map ( |artifacts| artifacts. values ( ) . flat_map ( |artifacts| artifacts. values ( ) ) )
862+ . flat_map ( |artifacts| artifacts. values ( ) )
863+ . flat_map ( |artifacts| artifacts. values ( ) )
864+ . flat_map ( |artifacts| artifacts. values ( ) )
858865 . map ( |a| a. path . to_slash_lossy ( ) . to_lowercase ( ) )
859866 . collect :: < HashSet < _ > > ( ) ;
860867
@@ -865,22 +872,26 @@ pub trait ArtifactOutput {
865872 } ) ;
866873 for file in files {
867874 for ( name, versioned_contracts) in & contracts[ file] {
875+ let unique_versions =
876+ versioned_contracts. iter ( ) . map ( |c| & c. version ) . collect :: < HashSet < _ > > ( ) ;
877+ let unique_profiles =
878+ versioned_contracts. iter ( ) . map ( |c| & c. profile ) . collect :: < HashSet < _ > > ( ) ;
868879 for contract in versioned_contracts {
880+ non_standalone_sources. insert ( file) ;
881+
869882 // track `SourceFile`s that can be mapped to contracts
870883 let source_file = sources. find_file_and_version ( file, & contract. version ) ;
871884
872- if let Some ( source) = source_file {
873- non_standalone_sources. insert ( ( source. id , & contract. version ) ) ;
874- }
875-
876885 let artifact_path = Self :: get_artifact_path (
877886 & ctx,
878887 & taken_paths_lowercase,
879888 file,
880889 name,
881890 layout. artifacts . as_path ( ) ,
882891 & contract. version ,
883- versioned_contracts. len ( ) > 1 ,
892+ & contract. profile ,
893+ unique_versions. len ( ) > 1 ,
894+ unique_profiles. len ( ) > 1 ,
884895 ) ;
885896
886897 taken_paths_lowercase. insert ( artifact_path. to_slash_lossy ( ) . to_lowercase ( ) ) ;
@@ -904,6 +915,7 @@ pub trait ArtifactOutput {
904915 file : artifact_path,
905916 version : contract. version . clone ( ) ,
906917 build_id : contract. build_id . clone ( ) ,
918+ profile : contract. profile . clone ( ) ,
907919 } ;
908920
909921 artifacts
@@ -921,8 +933,10 @@ pub trait ArtifactOutput {
921933 // any contract definition, which are not included in the `CompilerOutput` but we want to
922934 // create Artifacts for them regardless
923935 for ( file, sources) in sources. as_ref ( ) . iter ( ) {
936+ let unique_versions = sources. iter ( ) . map ( |s| & s. version ) . collect :: < HashSet < _ > > ( ) ;
937+ let unique_profiles = sources. iter ( ) . map ( |s| & s. profile ) . collect :: < HashSet < _ > > ( ) ;
924938 for source in sources {
925- if !non_standalone_sources. contains ( & ( source . source_file . id , & source . version ) ) {
939+ if !non_standalone_sources. contains ( file ) {
926940 // scan the ast as a safe measure to ensure this file does not include any
927941 // source units
928942 // there's also no need to create a standalone artifact for source files that
@@ -945,26 +959,26 @@ pub trait ArtifactOutput {
945959 name,
946960 & layout. artifacts ,
947961 & source. version ,
948- sources. len ( ) > 1 ,
962+ & source. profile ,
963+ unique_versions. len ( ) > 1 ,
964+ unique_profiles. len ( ) > 1 ,
949965 ) ;
950966
951- let entries = artifacts
967+ taken_paths_lowercase
968+ . insert ( artifact_path. to_slash_lossy ( ) . to_lowercase ( ) ) ;
969+
970+ artifacts
952971 . entry ( file. clone ( ) )
953972 . or_default ( )
954973 . entry ( name. to_string ( ) )
955- . or_default ( ) ;
956-
957- if entries. iter ( ) . all ( |entry| entry. version != source. version ) {
958- taken_paths_lowercase
959- . insert ( artifact_path. to_slash_lossy ( ) . to_lowercase ( ) ) ;
960-
961- entries. push ( ArtifactFile {
974+ . or_default ( )
975+ . push ( ArtifactFile {
962976 artifact,
963977 file : artifact_path,
964978 version : source. version . clone ( ) ,
965979 build_id : source. build_id . clone ( ) ,
980+ profile : source. profile . clone ( ) ,
966981 } ) ;
967- }
968982 }
969983 }
970984 }
@@ -1015,8 +1029,7 @@ pub struct OutputContext<'a> {
10151029 /// └── inner
10161030 /// └── a.sol
10171031 /// ```
1018- pub existing_artifacts :
1019- BTreeMap < & ' a Path , & ' a BTreeMap < String , BTreeMap < Version , CachedArtifact > > > ,
1032+ pub existing_artifacts : BTreeMap < & ' a Path , & ' a CachedArtifacts > ,
10201033}
10211034
10221035// === impl OutputContext
@@ -1042,13 +1055,14 @@ impl<'a> OutputContext<'a> {
10421055 file : & Path ,
10431056 contract : & str ,
10441057 version : & Version ,
1058+ profile : & str ,
10451059 ) -> 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- } )
1060+ self . existing_artifacts
1061+ . get ( file )
1062+ . and_then ( |contracts| contracts . get ( contract) )
1063+ . and_then ( |versions| versions. get ( version) )
1064+ . and_then ( |profiles| profiles . get ( profile ) )
1065+ . map ( |a| a . path . as_path ( ) )
10521066 }
10531067}
10541068
0 commit comments