@@ -32,9 +32,11 @@ public class PackageBuilder : IPackageMetadata
3232 private static readonly DateTime ZipFormatMinDate = new DateTime ( 1980 , 1 , 1 , 0 , 0 , 0 , DateTimeKind . Utc ) ;
3333 private static readonly DateTime ZipFormatMaxDate = new DateTime ( 2107 , 12 , 31 , 23 , 59 , 58 , DateTimeKind . Utc ) ;
3434 internal const string ManifestRelationType = "manifest" ;
35+ private readonly IEnvironmentVariableReader _environmentVariableProvider ;
3536 private readonly bool _includeEmptyDirectories ;
3637 private readonly bool _deterministic ;
3738 private readonly ILogger _logger ;
39+ private readonly DateTime _deterministicDate ;
3840
3941 /// <summary>
4042 /// Maximum Icon file size: 1 megabyte
@@ -68,7 +70,7 @@ public PackageBuilder(string path, string basePath, Func<string, string> propert
6870 }
6971
7072 public PackageBuilder ( string path , string basePath , Func < string , string > propertyProvider , bool includeEmptyDirectories , bool deterministic )
71- : this ( includeEmptyDirectories , deterministic )
73+ : this ( EnvironmentVariableWrapper . Instance , includeEmptyDirectories , deterministic )
7274 {
7375 if ( ! File . Exists ( path ) )
7476 {
@@ -95,30 +97,32 @@ public PackageBuilder(Stream stream, string basePath, Func<string, string> prope
9597 }
9698
9799 public PackageBuilder ( bool deterministic ) :
98- this ( includeEmptyDirectories : false , deterministic : deterministic )
100+ this ( EnvironmentVariableWrapper . Instance , includeEmptyDirectories : false , deterministic : deterministic )
99101 {
100102
101103 }
102104
103105 public PackageBuilder ( )
104- : this ( includeEmptyDirectories : false , deterministic : false )
106+ : this ( EnvironmentVariableWrapper . Instance , includeEmptyDirectories : false , deterministic : false )
105107 {
106108 }
107109
108110 public PackageBuilder ( bool deterministic , ILogger logger )
109- : this ( includeEmptyDirectories : false , deterministic : deterministic , logger )
111+ : this ( EnvironmentVariableWrapper . Instance , includeEmptyDirectories : false , deterministic : deterministic , logger )
110112 {
111113 }
112114
113- private PackageBuilder ( bool includeEmptyDirectories , bool deterministic )
114- : this ( includeEmptyDirectories : false , deterministic : deterministic , logger : NullLogger . Instance )
115+ private PackageBuilder ( IEnvironmentVariableReader environmentVariableProvider , bool includeEmptyDirectories , bool deterministic )
116+ : this ( environmentVariableProvider , includeEmptyDirectories : false , deterministic : deterministic , logger : NullLogger . Instance )
115117 {
116118 }
117119
118- private PackageBuilder ( bool includeEmptyDirectories , bool deterministic , ILogger logger )
120+ private PackageBuilder ( IEnvironmentVariableReader environmentVariableProvider , bool includeEmptyDirectories , bool deterministic , ILogger logger )
119121 {
122+ _environmentVariableProvider = environmentVariableProvider ;
120123 _includeEmptyDirectories = includeEmptyDirectories ;
121- _deterministic = false ; // fix in https://github.com/NuGet/Home/issues/8601
124+ _deterministic = deterministic ;
125+ _deterministicDate = ComputeDeterministicDate ( ) ;
122126 _logger = logger ;
123127 Files = new Collection < IPackageFile > ( ) ;
124128 DependencyGroups = new Collection < PackageDependencyGroup > ( ) ;
@@ -135,6 +139,20 @@ private PackageBuilder(bool includeEmptyDirectories, bool deterministic, ILogger
135139 Properties = new Dictionary < string , string > ( StringComparer . OrdinalIgnoreCase ) ;
136140 }
137141
142+ private DateTime ComputeDeterministicDate ( )
143+ {
144+ string sourceBuildEpoch = _environmentVariableProvider . GetEnvironmentVariable ( "SOURCE_DATE_EPOCH" ) ;
145+ if ( sourceBuildEpoch != null &&
146+ long . TryParse ( sourceBuildEpoch , NumberStyles . None , CultureInfo . InvariantCulture , out long unixTimeSeconds ) )
147+ {
148+ return DateTimeOffset . FromUnixTimeSeconds ( unixTimeSeconds ) . UtcDateTime ;
149+ }
150+ else
151+ {
152+ return ZipFormatMinDate ;
153+ }
154+ }
155+
138156 public string Id
139157 {
140158 get ;
@@ -1004,7 +1022,7 @@ private ZipArchiveEntry CreateEntry(ZipArchive package, string entryName, Compre
10041022 var entry = package . CreateEntry ( entryName , compressionLevel ) ;
10051023 if ( _deterministic )
10061024 {
1007- entry . LastWriteTime = ZipFormatMinDate ;
1025+ entry . LastWriteTime = _deterministicDate ;
10081026 }
10091027 return entry ;
10101028 }
@@ -1060,7 +1078,7 @@ private SortedSet<string> WriteFiles(ZipArchive package, SortedSet<string> files
10601078 package ,
10611079 file . Path ,
10621080 stream ,
1063- lastWriteTime : _deterministic ? ZipFormatMinDate : file . LastWriteTime ,
1081+ lastWriteTime : _deterministic ? _deterministicDate : file . LastWriteTime ,
10641082 warningMessage ) ;
10651083 var fileExtension = Path . GetExtension ( file . Path ) ;
10661084
0 commit comments