diff --git a/Kuinox.NupkgDeterministicator.Task/Kuinox.NupkgDeterministicator.Task.csproj b/Kuinox.NupkgDeterministicator.Task/Kuinox.NupkgDeterministicator.Task.csproj
new file mode 100644
index 0000000..cd24518
--- /dev/null
+++ b/Kuinox.NupkgDeterministicator.Task/Kuinox.NupkgDeterministicator.Task.csproj
@@ -0,0 +1,36 @@
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+ true
+ tools
+ false
+
+
+ PreserveNewest
+ true
+ tools
+ false
+
+
+
+
diff --git a/Kuinox.NupkgDeterministicator.Task/MakeNukpkgDeterministic.cs b/Kuinox.NupkgDeterministicator.Task/MakeNukpkgDeterministic.cs
new file mode 100644
index 0000000..2406e8b
--- /dev/null
+++ b/Kuinox.NupkgDeterministicator.Task/MakeNukpkgDeterministic.cs
@@ -0,0 +1,72 @@
+using Microsoft.Build.Framework;
+using Microsoft.Build.Utilities;
+using System;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+namespace Kuinox.NupkgDeterministicator.Task
+{
+ public sealed class MakeNukpkgDeterministic : ToolTask
+ {
+ ///
+ /// The zip to make deterministic.
+ ///
+ public string ZipPath { get; set; }
+
+ ///
+ /// The last write time to sets. Default to 2000-01-01.
+ ///
+ public DateTime LastWriteTime { get; set; } = new DateTime(2000, 1, 1);
+
+ ///
+ /// Used to identify the nupkg and symbols package
+ ///
+ public string PackageVersion { get; set; }
+
+ protected override string ToolName => Path.GetFileName(GetDotNetPath());
+
+ protected override string GenerateCommandLineCommands() => $"exec \"{ToolPath}\"";
+
+ protected override string GenerateResponseFileCommands() =>
+ ZipPath + " " + LastWriteTime.ToString(CultureInfo.InvariantCulture);
+
+
+ private const string DotNetHostPathEnvironmentName = "DOTNET_HOST_PATH";
+
+ // https://github.com/dotnet/roslyn/blob/020db28fa9b744146e6f072dbdc6bf3e62c901c1/src/Compilers/Shared/RuntimeHostInfo.cs#L59
+ private static string GetDotNetPath()
+ {
+ if (Environment.GetEnvironmentVariable(DotNetHostPathEnvironmentName) is string pathToDotNet)
+ {
+ return pathToDotNet;
+ }
+
+ var (fileName, sep) = Environment.OSVersion.Platform == PlatformID.Win32NT
+ ? ("dotnet.exe", ';')
+ : ("dotnet", ':');
+
+ var path = Environment.GetEnvironmentVariable("PATH") ?? "";
+ foreach (var item in path.Split(new[] { sep }, StringSplitOptions.RemoveEmptyEntries))
+ {
+ try
+ {
+ var filePath = Path.Combine(item, fileName);
+ if (File.Exists(filePath))
+ {
+ return filePath;
+ }
+ }
+ catch
+ {
+ // If we can't read a directory for any reason just skip it
+ }
+ }
+
+ return fileName;
+ }
+
+ protected override string GenerateFullPathToTool() => Path.GetFullPath(GetDotNetPath());
+ }
+}
diff --git a/Kuinox.NupkgDeterministicator.sln b/Kuinox.NupkgDeterministicator.sln
index d0cef2a..bd19d27 100644
--- a/Kuinox.NupkgDeterministicator.sln
+++ b/Kuinox.NupkgDeterministicator.sln
@@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.2.32408.312
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kuinox.NupkgDeterministicator", "Kuinox.NupkgDeterministicator\Kuinox.NupkgDeterministicator.csproj", "{BA1667CF-66CA-4C07-902A-6C577B1F7ED0}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Kuinox.NupkgDeterministicator", "Kuinox.NupkgDeterministicator\Kuinox.NupkgDeterministicator.csproj", "{BA1667CF-66CA-4C07-902A-6C577B1F7ED0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kuinox.NupkgDeterministicator.Task", "Kuinox.NupkgDeterministicator.Task\Kuinox.NupkgDeterministicator.Task.csproj", "{CC8B4D54-BCF7-4FB8-B2E0-845380DBAD99}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +17,10 @@ Global
{BA1667CF-66CA-4C07-902A-6C577B1F7ED0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BA1667CF-66CA-4C07-902A-6C577B1F7ED0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BA1667CF-66CA-4C07-902A-6C577B1F7ED0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CC8B4D54-BCF7-4FB8-B2E0-845380DBAD99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CC8B4D54-BCF7-4FB8-B2E0-845380DBAD99}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CC8B4D54-BCF7-4FB8-B2E0-845380DBAD99}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CC8B4D54-BCF7-4FB8-B2E0-845380DBAD99}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE