2018-11-22 04:57:18 +01:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Diagnostics;
|
2022-11-13 00:11:40 +01:00
|
|
|
using System.Globalization;
|
2018-11-22 04:57:18 +01:00
|
|
|
using System.IO;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Security.Cryptography;
|
2019-02-17 02:03:56 +01:00
|
|
|
using System.Text;
|
|
|
|
using System.Text.RegularExpressions;
|
2018-11-22 04:57:18 +01:00
|
|
|
using ICSharpCode.SharpZipLib.Zip;
|
2021-01-02 01:01:36 +01:00
|
|
|
using ICSharpCode.SharpZipLib.Zip.Compression;
|
2020-10-07 03:15:32 +02:00
|
|
|
using LibHacBuild.CodeGen.Stage1;
|
2018-11-22 04:57:18 +01:00
|
|
|
using Nuke.Common;
|
2019-10-15 04:10:53 +02:00
|
|
|
using Nuke.Common.CI.AppVeyor;
|
2018-11-22 04:57:18 +01:00
|
|
|
using Nuke.Common.Git;
|
2019-05-31 03:20:01 +02:00
|
|
|
using Nuke.Common.IO;
|
2018-11-22 04:57:18 +01:00
|
|
|
using Nuke.Common.ProjectModel;
|
2019-11-29 20:11:04 +01:00
|
|
|
using Nuke.Common.Tooling;
|
2018-11-22 04:57:18 +01:00
|
|
|
using Nuke.Common.Tools.DotNet;
|
2019-02-17 02:03:56 +01:00
|
|
|
using Nuke.Common.Tools.GitVersion;
|
|
|
|
using Nuke.Common.Tools.SignTool;
|
2018-11-22 04:57:18 +01:00
|
|
|
using static Nuke.Common.Tools.DotNet.DotNetTasks;
|
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
namespace LibHacBuild;
|
|
|
|
|
|
|
|
partial class Build : NukeBuild
|
2018-11-22 04:57:18 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
public static int Main() => Execute<Build>(x => x.Standard);
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
[Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")]
|
|
|
|
public readonly string Configuration = IsLocalBuild ? "Debug" : "Release";
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
[Parameter("Don't enable any size-reducing settings on native builds.")]
|
|
|
|
public readonly bool Untrimmed;
|
2019-11-28 02:52:20 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
[Parameter("Disable reflection in native builds.")]
|
|
|
|
public readonly bool NoReflection;
|
2020-06-28 01:01:46 +02:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
[Solution("LibHac.sln")] readonly Solution _solution;
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
AbsolutePath SourceDirectory => RootDirectory / "src";
|
|
|
|
AbsolutePath TestsDirectory => RootDirectory / "tests";
|
|
|
|
AbsolutePath ArtifactsDirectory => RootDirectory / "artifacts";
|
|
|
|
AbsolutePath SignedArtifactsDirectory => ArtifactsDirectory / "signed";
|
2021-12-17 08:59:18 +01:00
|
|
|
AbsolutePath TempDirectory => RootDirectory / ".nuke" / "temp";
|
2022-11-16 02:53:22 +01:00
|
|
|
AbsolutePath CliCoreDir => TempDirectory / "hactoolnet_net7.0";
|
2021-11-14 20:08:57 +01:00
|
|
|
AbsolutePath CliNativeDir => TempDirectory / $"hactoolnet_{HostOsName}";
|
|
|
|
AbsolutePath CliNativeExe => CliNativeDir / $"hactoolnet{NativeProgramExtension}";
|
|
|
|
AbsolutePath CliCoreZip => ArtifactsDirectory / $"hactoolnet-{VersionString}-netcore.zip";
|
|
|
|
AbsolutePath CliNativeZip => ArtifactsDirectory / $"hactoolnet-{VersionString}-{HostOsName}.zip";
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Project LibHacProject => _solution.GetProject("LibHac").NotNull();
|
|
|
|
Project LibHacTestProject => _solution.GetProject("LibHac.Tests").NotNull();
|
|
|
|
Project HactoolnetProject => _solution.GetProject("hactoolnet").NotNull();
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Project CodeGenProject => _solution.GetProject("_buildCodeGen").NotNull();
|
2020-10-07 03:15:32 +02:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
private bool HasGitDir { get; set; }
|
2019-12-31 07:05:29 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
private string NativeRuntime { get; set; }
|
|
|
|
private string HostOsName { get; set; }
|
|
|
|
private string NativeProgramExtension { get; set; }
|
2019-11-28 02:52:20 +01:00
|
|
|
|
2022-11-13 00:11:40 +01:00
|
|
|
private DateTimeOffset CommitTime { get; set; } = DateTimeOffset.Now;
|
2021-11-14 20:08:57 +01:00
|
|
|
string VersionString { get; set; }
|
|
|
|
Dictionary<string, object> VersionProps { get; set; } = new Dictionary<string, object>();
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
const string CertFileName = "cert.pfx";
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
public Build()
|
|
|
|
{
|
|
|
|
if (EnvironmentInfo.IsWin)
|
2019-11-28 02:52:20 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
NativeRuntime = "win-x64";
|
|
|
|
NativeProgramExtension = ".exe";
|
|
|
|
HostOsName = "win";
|
|
|
|
}
|
|
|
|
else if (EnvironmentInfo.IsLinux)
|
|
|
|
{
|
|
|
|
NativeRuntime = "linux-x64";
|
|
|
|
NativeProgramExtension = "";
|
|
|
|
HostOsName = "linux";
|
|
|
|
}
|
|
|
|
else if (EnvironmentInfo.IsOsx)
|
|
|
|
{
|
|
|
|
NativeRuntime = "osx-x64";
|
|
|
|
NativeProgramExtension = "";
|
|
|
|
HostOsName = "macos";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Target SetVersion => _ => _
|
|
|
|
.Executes(() =>
|
|
|
|
{
|
|
|
|
GitRepository gitRepository = null;
|
|
|
|
GitVersion gitVersion = null;
|
|
|
|
|
|
|
|
try
|
2019-11-28 02:52:20 +01:00
|
|
|
{
|
2023-10-09 06:03:56 +02:00
|
|
|
gitRepository = GitRepository.FromLocalDirectory(RootDirectory);
|
2021-11-14 20:08:57 +01:00
|
|
|
|
|
|
|
gitVersion = GitVersionTasks.GitVersion(s => s
|
|
|
|
.DisableProcessLogOutput())
|
|
|
|
.Result;
|
2019-11-28 02:52:20 +01:00
|
|
|
}
|
2021-11-14 20:08:57 +01:00
|
|
|
catch (Exception e)
|
2019-11-28 02:52:20 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
if (!e.Message.Contains("not a git repository", StringComparison.OrdinalIgnoreCase))
|
|
|
|
{
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Error(e, e.Message);
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
2019-11-28 02:52:20 +01:00
|
|
|
}
|
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
if (gitRepository == null || gitVersion == null)
|
2019-02-17 02:03:56 +01:00
|
|
|
{
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Debug("Unable to read Git version.");
|
2019-12-31 07:05:29 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
VersionString = GetCsprojVersion();
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Debug($"Using version from .csproj: {VersionString}");
|
2019-12-31 07:05:29 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
return;
|
|
|
|
}
|
2020-08-16 08:19:27 +02:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
HasGitDir = true;
|
2020-08-16 08:19:27 +02:00
|
|
|
|
2022-11-13 00:11:40 +01:00
|
|
|
if (DateTimeOffset.TryParseExact(gitVersion.CommitDate, "yyyy-MM-dd HH:mm:ss",
|
2023-10-09 06:03:56 +02:00
|
|
|
CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.AssumeUniversal, out DateTimeOffset commitTime))
|
2022-11-13 00:11:40 +01:00
|
|
|
{
|
|
|
|
CommitTime = commitTime.LocalDateTime;
|
|
|
|
}
|
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
VersionString = $"{gitVersion.MajorMinorPatch}";
|
|
|
|
if (!string.IsNullOrWhiteSpace(gitVersion.PreReleaseTag))
|
|
|
|
{
|
|
|
|
VersionString += $"-{gitVersion.PreReleaseTag}+{gitVersion.Sha.Substring(0, 8)}";
|
|
|
|
}
|
2019-12-31 07:05:29 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
string suffix = gitVersion.PreReleaseTag;
|
2019-12-31 07:05:29 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
if (!string.IsNullOrWhiteSpace(suffix))
|
|
|
|
{
|
|
|
|
if (!gitRepository.IsOnMasterBranch())
|
2019-12-31 07:05:29 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
suffix = $"-{suffix}";
|
2019-12-31 07:05:29 +01:00
|
|
|
}
|
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
suffix += $"+{gitVersion.Sha.Substring(0, 8)}";
|
|
|
|
}
|
|
|
|
|
2021-12-17 08:59:18 +01:00
|
|
|
if (Host is AppVeyor appVeyor)
|
2021-11-14 20:08:57 +01:00
|
|
|
{
|
2021-12-17 08:59:18 +01:00
|
|
|
// Workaround GitVersion issue by getting PR info manually https://github.com/GitTools/GitVersion/issues/1927
|
|
|
|
int? prNumber = appVeyor.PullRequestNumber;
|
2021-11-14 20:08:57 +01:00
|
|
|
string branchName = Environment.GetEnvironmentVariable("APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH");
|
2019-02-17 03:31:35 +01:00
|
|
|
|
2021-12-17 08:59:18 +01:00
|
|
|
if (prNumber != null && branchName != null)
|
2019-02-17 03:31:35 +01:00
|
|
|
{
|
2021-12-17 08:59:18 +01:00
|
|
|
string prString = $"PullRequest{prNumber:D4}";
|
2019-02-17 03:31:35 +01:00
|
|
|
|
2023-10-09 09:41:47 +02:00
|
|
|
VersionString = VersionString.Replace(gitVersion.EscapedBranchName, prString);
|
|
|
|
suffix = suffix?.Replace(gitVersion.EscapedBranchName, prString) ?? "";
|
2019-12-31 07:05:29 +01:00
|
|
|
}
|
|
|
|
|
2021-12-17 08:59:18 +01:00
|
|
|
appVeyor.UpdateBuildVersion(VersionString);
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
2019-12-31 07:05:29 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
VersionProps = new Dictionary<string, object>
|
|
|
|
{
|
|
|
|
["VersionPrefix"] = gitVersion.AssemblySemVer,
|
|
|
|
["VersionSuffix"] = suffix
|
|
|
|
};
|
2019-12-31 07:05:29 +01:00
|
|
|
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Debug($"Building version {VersionString}");
|
2021-11-14 20:08:57 +01:00
|
|
|
});
|
2019-12-31 07:05:29 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Target Clean => _ => _
|
|
|
|
.Executes(() =>
|
|
|
|
{
|
2023-10-09 06:03:56 +02:00
|
|
|
List<AbsolutePath> toDelete = SourceDirectory.GlobDirectories("**/bin", "**/obj")
|
|
|
|
.Concat(TestsDirectory.GlobDirectories("**/bin", "**/obj")).ToList();
|
2019-02-17 03:31:35 +01:00
|
|
|
|
2023-10-09 06:03:56 +02:00
|
|
|
foreach (AbsolutePath dir in toDelete)
|
2021-11-14 20:08:57 +01:00
|
|
|
{
|
2023-10-09 06:03:56 +02:00
|
|
|
dir.DeleteDirectory();
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2023-10-09 06:03:56 +02:00
|
|
|
ArtifactsDirectory.CreateOrCleanDirectory();
|
|
|
|
CliCoreDir.CreateOrCleanDirectory();
|
|
|
|
CliNativeDir.CreateOrCleanDirectory();
|
2021-11-14 20:08:57 +01:00
|
|
|
});
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Target Restore => _ => _
|
|
|
|
.DependsOn(Clean)
|
|
|
|
.Executes(() =>
|
|
|
|
{
|
|
|
|
DotNetRestoreSettings settings = new DotNetRestoreSettings()
|
|
|
|
.SetProjectFile(_solution);
|
2019-05-31 03:20:01 +02:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
DotNetRestore(s => settings);
|
|
|
|
});
|
2019-05-31 03:20:01 +02:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Target Codegen => _ => _
|
|
|
|
.Executes(() =>
|
|
|
|
{
|
|
|
|
ResultCodeGen.Run();
|
|
|
|
RunCodegenStage2();
|
|
|
|
});
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Target Compile => _ => _
|
|
|
|
.DependsOn(Restore, SetVersion, Codegen)
|
|
|
|
.Executes(() =>
|
|
|
|
{
|
|
|
|
DotNetBuildSettings buildSettings = new DotNetBuildSettings()
|
|
|
|
.SetProjectFile(_solution)
|
|
|
|
.EnableNoRestore()
|
|
|
|
.SetConfiguration(Configuration)
|
|
|
|
.SetProperties(VersionProps)
|
|
|
|
.SetProperty("BuildType", "Release")
|
|
|
|
.SetProperty("HasGitDir", HasGitDir);
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
DotNetBuild(s => buildSettings);
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
DotNetPublishSettings publishSettings = new DotNetPublishSettings()
|
|
|
|
.EnableNoRestore()
|
|
|
|
.SetConfiguration(Configuration);
|
2020-02-24 22:45:51 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
DotNetPublish(s => publishSettings
|
|
|
|
.SetProject(HactoolnetProject)
|
2022-11-16 02:53:22 +01:00
|
|
|
.SetFramework("net7.0")
|
2021-11-14 20:08:57 +01:00
|
|
|
.SetOutput(CliCoreDir)
|
|
|
|
.SetNoBuild(true)
|
|
|
|
.SetProperties(VersionProps));
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-12-17 08:59:18 +01:00
|
|
|
// Hack around OS newline differences
|
|
|
|
if (EnvironmentInfo.IsUnix)
|
2019-02-17 02:03:56 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
foreach (string filename in Directory.EnumerateFiles(CliCoreDir, "*.json"))
|
2019-02-17 02:03:56 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
ReplaceLineEndings(filename);
|
2019-02-17 02:03:56 +01:00
|
|
|
}
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
|
|
|
});
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Target Pack => _ => _
|
|
|
|
.DependsOn(Compile)
|
|
|
|
.Executes(() =>
|
|
|
|
{
|
|
|
|
DotNetPackSettings settings = new DotNetPackSettings()
|
|
|
|
.SetProject(LibHacProject)
|
|
|
|
.EnableNoBuild()
|
|
|
|
.SetConfiguration(Configuration)
|
|
|
|
.EnableIncludeSymbols()
|
|
|
|
.SetSymbolPackageFormat(DotNetSymbolPackageFormat.snupkg)
|
|
|
|
.SetOutputDirectory(ArtifactsDirectory)
|
|
|
|
.SetProperties(VersionProps);
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
DotNetPack(s => settings);
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
foreach (string filename in Directory.EnumerateFiles(ArtifactsDirectory, "*.*nupkg"))
|
2018-11-22 04:57:18 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
RepackNugetPackage(filename);
|
|
|
|
}
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
foreach (string filename in Directory.EnumerateFiles(ArtifactsDirectory, "*.*nupkg"))
|
2018-11-22 04:57:18 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
PushArtifact(filename);
|
|
|
|
}
|
|
|
|
});
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Target Test => _ => _
|
|
|
|
.DependsOn(Compile)
|
|
|
|
.Executes(() =>
|
|
|
|
{
|
|
|
|
DotNetTestSettings settings = new DotNetTestSettings()
|
|
|
|
.SetProjectFile(LibHacTestProject)
|
|
|
|
.EnableNoBuild()
|
|
|
|
.SetConfiguration(Configuration);
|
2020-01-17 08:01:25 +01:00
|
|
|
|
2022-11-16 02:53:22 +01:00
|
|
|
if (EnvironmentInfo.IsUnix) settings = settings.SetProperty("TargetFramework", "net7.0");
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
DotNetTest(s => settings);
|
|
|
|
});
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Target Zip => _ => _
|
|
|
|
.DependsOn(Pack)
|
|
|
|
.After(Native)
|
|
|
|
.Executes(() =>
|
|
|
|
{
|
|
|
|
string[] namesCore = Directory.EnumerateFiles(CliCoreDir, "*.json")
|
|
|
|
.Concat(Directory.EnumerateFiles(CliCoreDir, "*.dll"))
|
|
|
|
.ToArray();
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2023-10-09 06:03:56 +02:00
|
|
|
ArtifactsDirectory.CreateDirectory();
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2022-11-13 00:11:40 +01:00
|
|
|
ZipFiles(CliCoreZip, namesCore, CommitTime);
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Debug($"Created {CliCoreZip}");
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-12-17 08:59:18 +01:00
|
|
|
PushArtifact(CliCoreZip);
|
2021-11-14 20:08:57 +01:00
|
|
|
});
|
2019-06-07 00:15:43 +02:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Target Publish => _ => _
|
|
|
|
.DependsOn(Test, Pack)
|
|
|
|
.OnlyWhenStatic(() => AppVeyor.Instance != null && AppVeyor.Instance.PullRequestTitle == null)
|
|
|
|
.Executes(() =>
|
|
|
|
{
|
|
|
|
AbsolutePath nupkgFile = ArtifactsDirectory.GlobFiles("*.nupkg").Single();
|
2019-11-29 20:11:04 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
string apiKey = EnvironmentInfo.GetVariable<string>("myget_api_key");
|
|
|
|
DotNetNuGetPushSettings settings = new DotNetNuGetPushSettings()
|
|
|
|
.SetApiKey(apiKey)
|
|
|
|
.SetSource("https://www.myget.org/F/libhac/api/v3/index.json");
|
2019-06-07 00:15:43 +02:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
DotNetNuGetPush(settings.SetTargetPath(nupkgFile));
|
|
|
|
});
|
2019-06-07 00:15:43 +02:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Target Sign => _ => _
|
|
|
|
.DependsOn(Test, Zip)
|
|
|
|
.OnlyWhenStatic(() => File.Exists(CertFileName))
|
|
|
|
.OnlyWhenStatic(() => EnvironmentInfo.IsWin)
|
2022-01-10 02:13:53 +01:00
|
|
|
.WhenSkipped(DependencyBehavior.Execute)
|
2021-11-14 20:08:57 +01:00
|
|
|
.Executes(() =>
|
|
|
|
{
|
|
|
|
string pwd = ReadPassword();
|
2019-06-07 00:15:43 +02:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
if (pwd == string.Empty)
|
|
|
|
{
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Debug("Skipping sign task");
|
2021-11-14 20:08:57 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
SignAndReZip(pwd);
|
|
|
|
});
|
|
|
|
|
|
|
|
Target Native => _ => _
|
|
|
|
.DependsOn(SetVersion)
|
|
|
|
.After(Compile)
|
|
|
|
.Executes(BuildNative);
|
|
|
|
|
|
|
|
// ReSharper disable once UnusedMember.Local
|
|
|
|
Target AppVeyorBuild => _ => _
|
2022-02-20 04:07:10 +01:00
|
|
|
.DependsOn(Zip, Native, Test, Publish)
|
2021-11-14 20:08:57 +01:00
|
|
|
.Unlisted()
|
|
|
|
.Executes(PrintResults);
|
2019-06-07 00:15:43 +02:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Target Standard => _ => _
|
|
|
|
.DependsOn(Test, Zip)
|
|
|
|
.Executes(PrintResults);
|
2019-11-28 02:52:20 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
// ReSharper disable once UnusedMember.Local
|
|
|
|
Target Full => _ => _
|
|
|
|
.DependsOn(Sign, Native)
|
|
|
|
.Executes(PrintResults);
|
|
|
|
|
|
|
|
public void PrintResults()
|
|
|
|
{
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Debug("SHA-1:");
|
2021-11-14 20:08:57 +01:00
|
|
|
using (var sha = SHA1.Create())
|
2019-11-29 20:11:04 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
foreach (string filename in Directory.EnumerateFiles(ArtifactsDirectory))
|
2019-11-29 20:11:04 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
using (var stream = new FileStream(filename, FileMode.Open))
|
2019-11-29 20:11:04 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
string hash = BitConverter.ToString(sha.ComputeHash(stream)).Replace("-", "");
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Debug($"{hash} - {Path.GetFileName(filename)}");
|
2019-11-29 20:11:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public void BuildNative()
|
|
|
|
{
|
|
|
|
string buildType = Untrimmed ? "native-untrimmed" : "native";
|
2019-11-28 02:52:20 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
if (NoReflection)
|
2019-11-29 20:11:04 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
buildType = "native-noreflection";
|
|
|
|
}
|
2019-06-07 00:15:43 +02:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
DotNetPublishSettings publishSettings = new DotNetPublishSettings()
|
|
|
|
.SetConfiguration(Configuration)
|
|
|
|
.SetProject(HactoolnetProject)
|
|
|
|
.SetRuntime(NativeRuntime)
|
2021-12-17 23:37:14 +01:00
|
|
|
.SetSelfContained(true)
|
2021-11-14 20:08:57 +01:00
|
|
|
.SetOutput(CliNativeDir)
|
|
|
|
.SetProperties(VersionProps)
|
|
|
|
.AddProperty("BuildType", buildType);
|
2020-06-28 01:01:46 +02:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
DotNetPublish(publishSettings);
|
2019-11-29 20:11:04 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
if (EnvironmentInfo.IsUnix && !Untrimmed)
|
|
|
|
{
|
|
|
|
File.Copy(CliNativeExe, CliNativeExe + "_unstripped", true);
|
|
|
|
ProcessTasks.StartProcess("strip", CliNativeExe).AssertZeroExitCode();
|
|
|
|
}
|
2019-06-07 00:15:43 +02:00
|
|
|
|
2023-10-09 06:03:56 +02:00
|
|
|
ArtifactsDirectory.CreateOrCleanDirectory();
|
2019-11-29 20:11:04 +01:00
|
|
|
|
2022-11-13 00:11:40 +01:00
|
|
|
ZipFile(CliNativeZip, CliNativeExe, $"hactoolnet{NativeProgramExtension}", CommitTime);
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Debug($"Created {CliNativeZip}");
|
|
|
|
Serilog.Log.Debug($"Created {CliNativeZip}");
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-12-17 08:59:18 +01:00
|
|
|
PushArtifact(CliNativeZip);
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2022-11-13 00:11:40 +01:00
|
|
|
public static void ZipFiles(string outFile, IEnumerable<string> files, DateTimeOffset fileDateTime)
|
2021-11-14 20:08:57 +01:00
|
|
|
{
|
|
|
|
using (var s = new ZipOutputStream(File.Create(outFile)))
|
|
|
|
{
|
|
|
|
s.SetLevel(9);
|
|
|
|
|
|
|
|
foreach (string file in files)
|
2019-11-29 20:11:04 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
var entry = new ZipEntry(Path.GetFileName(file));
|
2022-11-13 00:11:40 +01:00
|
|
|
entry.DateTime = fileDateTime.DateTime;
|
2021-11-14 20:08:57 +01:00
|
|
|
|
|
|
|
using (FileStream fs = File.OpenRead(file))
|
|
|
|
{
|
|
|
|
entry.Size = fs.Length;
|
|
|
|
s.PutNextEntry(entry);
|
|
|
|
fs.CopyTo(s);
|
|
|
|
}
|
2019-11-29 20:11:04 +01:00
|
|
|
}
|
|
|
|
}
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2022-11-13 00:11:40 +01:00
|
|
|
public static void ZipFile(string outFile, string file, string nameInsideZip, DateTimeOffset fileDateTime)
|
2021-11-14 20:08:57 +01:00
|
|
|
{
|
|
|
|
using (var s = new ZipOutputStream(File.Create(outFile)))
|
2019-02-17 02:03:56 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
s.SetLevel(9);
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
var entry = new ZipEntry(nameInsideZip);
|
2022-11-13 00:11:40 +01:00
|
|
|
entry.DateTime = fileDateTime.DateTime;
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
using (FileStream fs = File.OpenRead(file))
|
|
|
|
{
|
|
|
|
entry.Size = fs.Length;
|
|
|
|
s.PutNextEntry(entry);
|
|
|
|
fs.CopyTo(s);
|
2018-11-22 04:57:18 +01:00
|
|
|
}
|
2019-02-17 02:03:56 +01:00
|
|
|
}
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2022-11-13 00:11:40 +01:00
|
|
|
public static void ZipDirectory(string outFile, string directory, DateTimeOffset fileDateTime)
|
2021-11-14 20:08:57 +01:00
|
|
|
{
|
|
|
|
using (var s = new ZipOutputStream(File.Create(outFile)))
|
2019-11-29 20:11:04 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
s.SetLevel(9);
|
|
|
|
|
|
|
|
foreach (string filePath in Directory.EnumerateFiles(directory, "*", SearchOption.AllDirectories))
|
2019-11-29 20:11:04 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
string relativePath = Path.GetRelativePath(directory, filePath);
|
2019-11-29 20:11:04 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
var entry = new ZipEntry(relativePath);
|
2022-11-13 00:11:40 +01:00
|
|
|
entry.DateTime = fileDateTime.DateTime;
|
2019-11-29 20:11:04 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
using (FileStream fs = File.OpenRead(filePath))
|
2019-11-29 20:11:04 +01:00
|
|
|
{
|
|
|
|
entry.Size = fs.Length;
|
|
|
|
s.PutNextEntry(entry);
|
|
|
|
fs.CopyTo(s);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
2019-11-29 20:11:04 +01:00
|
|
|
|
2022-11-13 00:11:40 +01:00
|
|
|
public static void ZipDirectory(string outFile, string directory, IEnumerable<string> files, DateTimeOffset fileDateTime)
|
2021-11-14 20:08:57 +01:00
|
|
|
{
|
|
|
|
using (var s = new ZipOutputStream(File.Create(outFile)))
|
2018-11-22 04:57:18 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
s.SetLevel(9);
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
foreach (string filePath in files)
|
|
|
|
{
|
|
|
|
string absolutePath = Path.Combine(directory, filePath);
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
var entry = new ZipEntry(filePath);
|
2022-11-13 00:11:40 +01:00
|
|
|
entry.DateTime = fileDateTime.DateTime;
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
using (FileStream fs = File.OpenRead(absolutePath))
|
|
|
|
{
|
|
|
|
entry.Size = fs.Length;
|
|
|
|
s.PutNextEntry(entry);
|
|
|
|
fs.CopyTo(s);
|
2018-11-22 04:57:18 +01:00
|
|
|
}
|
|
|
|
}
|
2019-02-17 02:03:56 +01:00
|
|
|
}
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
public static void UnzipFiles(string zipFile, string outDir)
|
|
|
|
{
|
|
|
|
using (var s = new ZipInputStream(File.OpenRead(zipFile)))
|
2018-11-22 04:57:18 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
ZipEntry entry;
|
|
|
|
while ((entry = s.GetNextEntry()) != null)
|
2018-11-22 04:57:18 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
string outPath = Path.Combine(outDir, entry.Name);
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
string directoryName = Path.GetDirectoryName(outPath);
|
|
|
|
string fileName = Path.GetFileName(outPath);
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
if (!string.IsNullOrWhiteSpace(directoryName))
|
|
|
|
{
|
|
|
|
Directory.CreateDirectory(directoryName);
|
2018-11-22 04:57:18 +01:00
|
|
|
}
|
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
if (!string.IsNullOrWhiteSpace(fileName))
|
2019-02-17 02:03:56 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
using (FileStream outFile = File.Create(outPath))
|
2019-02-17 02:03:56 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
s.CopyTo(outFile);
|
2019-02-17 02:03:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-11-22 04:57:18 +01:00
|
|
|
}
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
public static byte[] DeflateBytes(byte[] data)
|
|
|
|
{
|
|
|
|
var s = new Deflater(9, true);
|
|
|
|
s.SetInput(data);
|
|
|
|
s.Finish();
|
|
|
|
byte[] buffer = new byte[data.Length];
|
|
|
|
s.Deflate(buffer);
|
2021-01-02 01:01:36 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Debug.Assert(s.IsFinished);
|
2021-01-02 01:01:36 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
byte[] compressed = new byte[s.TotalOut];
|
|
|
|
Array.Copy(buffer, compressed, compressed.Length);
|
|
|
|
return compressed;
|
|
|
|
}
|
2021-01-02 01:01:36 +01:00
|
|
|
|
2021-12-17 08:59:18 +01:00
|
|
|
public static void PushArtifact(string path, string name = null)
|
2021-11-14 20:08:57 +01:00
|
|
|
{
|
2021-12-17 08:59:18 +01:00
|
|
|
if (Host is not AppVeyor appVeyor) return;
|
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
if (!File.Exists(path))
|
2018-11-22 04:57:18 +01:00
|
|
|
{
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Warning($"Unable to add artifact {path}");
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-12-17 08:59:18 +01:00
|
|
|
appVeyor.PushArtifact(path, name);
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Debug($"Added AppVeyor artifact {path}");
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
public static void ReplaceLineEndings(string filename)
|
|
|
|
{
|
|
|
|
string text = File.ReadAllText(filename);
|
|
|
|
File.WriteAllText(filename, Regex.Replace(text, @"\r\n|\n\r|\n|\r", "\r\n"));
|
|
|
|
}
|
2018-11-22 04:57:18 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
public static void SignAssemblies(string password, params string[] fileNames)
|
|
|
|
{
|
|
|
|
SignToolSettings settings = new SignToolSettings()
|
|
|
|
.SetFileDigestAlgorithm("SHA256")
|
|
|
|
.SetFile(CertFileName)
|
|
|
|
.SetFiles(fileNames)
|
|
|
|
.SetPassword(password)
|
|
|
|
.SetTimestampServerDigestAlgorithm("SHA256")
|
|
|
|
.SetRfc3161TimestampServerUrl("http://timestamp.digicert.com");
|
|
|
|
|
|
|
|
SignToolTasks.SignTool(settings);
|
|
|
|
}
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
public void SignAndReZip(string password)
|
|
|
|
{
|
|
|
|
AbsolutePath nupkgFile = ArtifactsDirectory.GlobFiles("*.nupkg").Single();
|
|
|
|
AbsolutePath snupkgFile = ArtifactsDirectory.GlobFiles("*.snupkg").Single();
|
|
|
|
AbsolutePath nupkgDir = TempDirectory / ("sign_" + Path.GetFileName(nupkgFile));
|
|
|
|
AbsolutePath coreFxDir = TempDirectory / ("sign_" + Path.GetFileName(CliCoreZip));
|
|
|
|
AbsolutePath nativeZipDir = TempDirectory / ("sign_" + Path.GetFileName(CliNativeZip));
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2022-04-02 04:57:16 +02:00
|
|
|
bool signNative = CliNativeExe.FileExists();
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
try
|
2019-02-17 02:03:56 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
UnzipFiles(CliCoreZip, coreFxDir);
|
|
|
|
List<string> pkgFileList = UnzipPackage(nupkgFile, nupkgDir);
|
2019-11-29 20:11:04 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
var toSign = new List<AbsolutePath>();
|
|
|
|
toSign.AddRange(nupkgDir.GlobFiles("**/LibHac.dll"));
|
|
|
|
toSign.Add(coreFxDir / "hactoolnet.dll");
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
if (signNative)
|
2019-02-17 02:03:56 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
UnzipFiles(CliNativeZip, nativeZipDir);
|
|
|
|
toSign.Add(nativeZipDir / "hactoolnet.exe");
|
|
|
|
}
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Directory.CreateDirectory(SignedArtifactsDirectory);
|
2019-11-29 20:11:04 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
SignAssemblies(password, toSign.Select(x => x.ToString()).ToArray());
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
// Avoid having multiple signed versions of the same file
|
2022-11-16 02:53:22 +01:00
|
|
|
File.Copy(nupkgDir / "lib" / "net7.0" / "LibHac.dll", coreFxDir / "LibHac.dll", true);
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2022-11-13 00:11:40 +01:00
|
|
|
ZipDirectory(SignedArtifactsDirectory / Path.GetFileName(nupkgFile), nupkgDir, pkgFileList, CommitTime);
|
|
|
|
ZipDirectory(SignedArtifactsDirectory / Path.GetFileName(CliCoreZip), coreFxDir, CommitTime);
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
if (signNative)
|
|
|
|
{
|
2022-11-13 00:11:40 +01:00
|
|
|
ZipDirectory(SignedArtifactsDirectory / Path.GetFileName(CliNativeZip), nativeZipDir, CommitTime);
|
2021-11-14 20:08:57 +01:00
|
|
|
}
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
File.Copy(snupkgFile, SignedArtifactsDirectory / Path.GetFileName(snupkgFile));
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
SignNupkg(SignedArtifactsDirectory / Path.GetFileName(nupkgFile), password);
|
|
|
|
SignNupkg(SignedArtifactsDirectory / Path.GetFileName(snupkgFile), password);
|
|
|
|
}
|
|
|
|
catch (Exception)
|
|
|
|
{
|
|
|
|
Directory.Delete(SignedArtifactsDirectory, true);
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
Directory.Delete(nupkgDir, true);
|
|
|
|
Directory.Delete(coreFxDir, true);
|
|
|
|
}
|
|
|
|
}
|
2019-11-29 20:11:04 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
public static string ReadPassword()
|
|
|
|
{
|
|
|
|
var pwd = new StringBuilder();
|
|
|
|
ConsoleKeyInfo key;
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Console.Write("Enter certificate password (Empty password to skip): ");
|
|
|
|
do
|
|
|
|
{
|
|
|
|
key = Console.ReadKey(true);
|
|
|
|
|
|
|
|
// Ignore any key out of range.
|
|
|
|
if (((int)key.Key) >= '!' && ((int)key.Key <= '~'))
|
2019-02-17 02:03:56 +01:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
// Append the character to the password.
|
|
|
|
pwd.Append(key.KeyChar);
|
|
|
|
Console.Write("*");
|
2019-02-17 02:03:56 +01:00
|
|
|
}
|
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
// Exit if Enter key is pressed.
|
|
|
|
} while (key.Key != ConsoleKey.Enter);
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
Console.WriteLine();
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
return pwd.ToString();
|
|
|
|
}
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
public string GetCsprojVersion()
|
|
|
|
{
|
|
|
|
return XmlTasks.XmlPeekSingle(LibHacProject.Path, "/Project/PropertyGroup/VersionPrefix", null);
|
|
|
|
}
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
public void RunCodegenStage2()
|
|
|
|
{
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Debug("\nBuilding stage 2 codegen project.");
|
2019-02-17 02:03:56 +01:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
DotNetRunSettings settings = new DotNetRunSettings()
|
|
|
|
.SetProjectFile(CodeGenProject.Path);
|
|
|
|
// .SetLogOutput(false);
|
2020-08-16 08:19:27 +02:00
|
|
|
|
2021-11-14 20:08:57 +01:00
|
|
|
try
|
2020-08-16 08:19:27 +02:00
|
|
|
{
|
2021-11-14 20:08:57 +01:00
|
|
|
DotNetRun(settings);
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Debug("");
|
2020-08-16 08:19:27 +02:00
|
|
|
}
|
2021-11-14 20:08:57 +01:00
|
|
|
catch (ProcessException)
|
2020-10-07 03:15:32 +02:00
|
|
|
{
|
2022-04-02 04:57:16 +02:00
|
|
|
Serilog.Log.Error("\nError running stage 2 codegen. Skipping...\n");
|
2020-10-07 03:15:32 +02:00
|
|
|
}
|
2018-11-22 04:57:18 +01:00
|
|
|
}
|
2022-01-10 02:13:53 +01:00
|
|
|
}
|