Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c573639d96 | |||
| 02a65a6ce0 | |||
| 2490fb260d | |||
| c4d573a69e | |||
| 3fb20e57d1 | |||
| 59b623c170 | |||
| b52ae3ce03 | |||
| c7ec07cef2 | |||
| f41e83765a | |||
| 2e943882ec | |||
| e11c689602 | |||
| 320fee57b2 | |||
| 2b848baa33 | |||
| 9065d614e1 | |||
| 7d330e9368 | |||
| 61a4902ac4 | |||
| 08a221202f | |||
| d2f2f671a4 |
@@ -0,0 +1,48 @@
|
||||
name: Nightly Build and Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build-releases:
|
||||
name: 'Build and Release Nightly'
|
||||
runs-on: Debian-x86
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup .NET 11.0
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '11.0.100-preview.4.26230.115'
|
||||
|
||||
# Authenticate with your private Gitea NuGet registry
|
||||
- name: Add Gitea NuGet Source
|
||||
run: |
|
||||
dotnet nuget remove source "GiteaRegistry" || true
|
||||
dotnet nuget add source "https://git.main.qwsdcvghyu.com/api/packages/riley/nuget/index.json" --name "GiteaRegistry" --username "riley" --password "${{ secrets.PACKAGES_KEY }}" --store-password-in-clear-text
|
||||
|
||||
- name: 'Execute .NET Publish Target'
|
||||
run: dotnet build aeqw89.tools.Publish/aeqw89.tools.Publish.csproj -t:PublishAll
|
||||
|
||||
- name: Update Nightly Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
tag_name: nightly
|
||||
name: "Nightly Development Build"
|
||||
body: |
|
||||
Automated rolling nightly build from the latest commit on `main`.
|
||||
|
||||
**Commit:** ${{ github.sha }}
|
||||
prerelease: true
|
||||
files: |
|
||||
aeqw89.tools.Publish/dist/*.zip
|
||||
aeqw89.tools.Publish/dist/*.tar.gz
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,2 +1,3 @@
|
||||
bin/**
|
||||
obj/**
|
||||
**/bin
|
||||
**/obj
|
||||
**/dist
|
||||
@@ -135,21 +135,41 @@ sealed record CloudDestiantion(DestinationContext Context) : IDestination {
|
||||
}
|
||||
}
|
||||
|
||||
sealed record GithubDestination(DestinationContext Context, bool Verbose = false) : IDestination {
|
||||
|
||||
sealed record GitDestination(DestinationContext Context, string Source, string ApiKey, bool Verbose = false) : IDestination {
|
||||
private static Result<string, ReadableError> GetApiKey(string host) {
|
||||
var key = Environment.GetEnvironmentVariable($"git-{host}-packages-key");
|
||||
if (key is null) return new ReadableError(string.Format("No key stored in EnvironmentVariables with name {0}", $"git-{host}-packages-key"), false);
|
||||
return key.Ok();
|
||||
}
|
||||
public static Result<GitDestination, ReadableError> CreateForGitea(DestinationContext context, string repoOwner, bool verbose = false) {
|
||||
// gitea source structure = https://gitea.example.com/api/packages/{owner}/nuget/index.json
|
||||
var keyResult = GetApiKey("gitea");
|
||||
if (keyResult is ReadableError error) return error;
|
||||
return new GitDestination(context, $"https://git.main.qwsdcvghyu.com/api/packages/{repoOwner}/nuget/index.json", keyResult.Unwrap(), verbose).Ok();
|
||||
}
|
||||
|
||||
public static Result<GitDestination, ReadableError> CreateForGithub(DestinationContext context, string repoOwner, bool verbose = false) {
|
||||
// github source structure = https://nuget.pkg.github.com/NAMESPACE/index.json
|
||||
// namespace usually = repoOwner
|
||||
var keyResult = GetApiKey("github");
|
||||
if (keyResult is ReadableError error) return error;
|
||||
return new GitDestination(context, $"https://nuget.pkg.github.com/{repoOwner}/index.json", keyResult.Unwrap(), verbose).Ok();
|
||||
}
|
||||
|
||||
public async Task<Result<Success, ReadableError>> WaitForCompletion(CancellationToken ct = default) {
|
||||
var p = Process.Start(new ProcessStartInfo() {
|
||||
using var p = Process.Start(new ProcessStartInfo() {
|
||||
FileName = "dotnet",
|
||||
Arguments = $"nuget push \"{Context.PackageFile.FullName}\" --source github",
|
||||
Arguments = $"nuget push \"{Context.PackageFile.FullName}\" -s {Source} -k {ApiKey}",
|
||||
WorkingDirectory = Environment.CurrentDirectory,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true
|
||||
});
|
||||
|
||||
var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
|
||||
using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
|
||||
StringBuilder errorLines = new();
|
||||
p?.ErrorDataReceived += (sender, eventArgs) => {
|
||||
cts.Cancel();
|
||||
if (Verbose && eventArgs.Data != null)
|
||||
AnsiConsole.WriteLine(eventArgs.Data);
|
||||
errorLines.Append(eventArgs.Data);
|
||||
@@ -169,16 +189,16 @@ sealed record GithubDestination(DestinationContext Context, bool Verbose = false
|
||||
try {
|
||||
await (p?.WaitForExitAsync(cts.Token) ?? Task.CompletedTask);
|
||||
}
|
||||
catch (TaskCanceledException) {
|
||||
catch (OperationCanceledException) {
|
||||
p?.Kill();
|
||||
await (p?.WaitForExitAsync(ct));
|
||||
}
|
||||
|
||||
if (p?.ExitCode != 0) {
|
||||
Context.Task.StopTask();
|
||||
return new ReadableError(errorLines.ToString().EscapeMarkup() + "\n" + string.Format(Exceptions.dotnet_nuget_push_failure, p?.ExitCode ?? -1), false);
|
||||
}
|
||||
|
||||
Context.Task.Increment(Context.BufferSize / 2);
|
||||
Context.Task.Increment(Context.PackageSize / 2);
|
||||
return Success.AsResult();
|
||||
}
|
||||
}
|
||||
-224
@@ -1,224 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace aeqw89.tools.Publish {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Exceptions {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Exceptions() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("aeqw89.tools.Publish.Exceptions", typeof(Exceptions).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The cloud host '{0}' is not an entry on this user's config file..
|
||||
/// </summary>
|
||||
internal static string cloud_host_not_found {
|
||||
get {
|
||||
return ResourceManager.GetString("cloud_host_not_found", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The mode '{0}' is invalid, the valid modes are [overwrite|increment].
|
||||
/// </summary>
|
||||
internal static string could_not_parse_mode {
|
||||
get {
|
||||
return ResourceManager.GetString("could_not_parse_mode", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The increment target '{0}' is invalid, the valid increment targets are [patch|minor|patch].
|
||||
/// </summary>
|
||||
internal static string could_not_parse_target {
|
||||
get {
|
||||
return ResourceManager.GetString("could_not_parse_target", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The 'dotnet nuget push' command failed with error message '{0}'.
|
||||
/// </summary>
|
||||
internal static string dotnet_nuget_push_failure {
|
||||
get {
|
||||
return ResourceManager.GetString("dotnet_nuget_push_failure", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Failed to pack with exit code '{0}'; ensure that 'dotnet build' succeeds before running this program..
|
||||
/// </summary>
|
||||
internal static string dotnet_pack_failure {
|
||||
get {
|
||||
return ResourceManager.GetString("dotnet_pack_failure", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Could not delete temporary directory '{0}' due to error '{1}'.
|
||||
/// </summary>
|
||||
internal static string failed_to_clean_up {
|
||||
get {
|
||||
return ResourceManager.GetString("failed_to_clean_up", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Failde to prepare an upload directory on the path {0} for the remote host '{1}', after being detected as a {2} host. Server error is '{3}'.
|
||||
/// </summary>
|
||||
internal static string failed_to_prepare_server_directory {
|
||||
get {
|
||||
return ResourceManager.GetString("failed_to_prepare_server_directory", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The flag '{0}' requires exactly '{1}' parameters. You have entered '{2}'..
|
||||
/// </summary>
|
||||
internal static string flag_parameter_length_incorrect {
|
||||
get {
|
||||
return ResourceManager.GetString("flag_parameter_length_incorrect", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The '{0}' flag requires that argument with index '{1}' be of type '{2}'. You have entered '{3}' which has failed to be converted..
|
||||
/// </summary>
|
||||
internal static string flag_parameter_type_incorrect {
|
||||
get {
|
||||
return ResourceManager.GetString("flag_parameter_type_incorrect", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The directory '{0}' contains multiple .csproj files; this tool can only process one at a time..
|
||||
/// </summary>
|
||||
internal static string found_multiple_csproj {
|
||||
get {
|
||||
return ResourceManager.GetString("found_multiple_csproj", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Something went wrong loading this file; {0}.
|
||||
/// </summary>
|
||||
internal static string generic_error {
|
||||
get {
|
||||
return ResourceManager.GetString("generic_error", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to You must specify at least one destination..
|
||||
/// </summary>
|
||||
internal static string missing_destinations {
|
||||
get {
|
||||
return ResourceManager.GetString("missing_destinations", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to You must specify an increment target if you specified an increment mode; allowed increment targets are [patch|minor|major].
|
||||
/// </summary>
|
||||
internal static string missing_increment_target {
|
||||
get {
|
||||
return ResourceManager.GetString("missing_increment_target", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to You must specify a mode; allowed modes are [overwrite|increment].
|
||||
/// </summary>
|
||||
internal static string missing_mode {
|
||||
get {
|
||||
return ResourceManager.GetString("missing_mode", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to No project file was found within the current directory..
|
||||
/// </summary>
|
||||
internal static string no_project_in_directory {
|
||||
get {
|
||||
return ResourceManager.GetString("no_project_in_directory", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The project file '{0}' is irreparable becuase it is missing a '{1}' property, and the value cannot be guessed..
|
||||
/// </summary>
|
||||
internal static string project_file_irreparable {
|
||||
get {
|
||||
return ResourceManager.GetString("project_file_irreparable", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Something went wrong; an attempt was made to load a non .csproj file as a project file..
|
||||
/// </summary>
|
||||
internal static string tried_loading_non_csproj_file {
|
||||
get {
|
||||
return ResourceManager.GetString("tried_loading_non_csproj_file", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The version string '{0}' is in an unidentifiable format..
|
||||
/// </summary>
|
||||
internal static string version_string_not_formatted_correctly {
|
||||
get {
|
||||
return ResourceManager.GetString("version_string_not_formatted_correctly", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ using Renci.SshNet;
|
||||
using Spectre.Console;
|
||||
using aeqw89.xml.ProjectFile;
|
||||
|
||||
|
||||
namespace aeqw89.tools.Publish;
|
||||
|
||||
/*
|
||||
@@ -116,7 +115,7 @@ public static class Program {
|
||||
return result;
|
||||
}
|
||||
|
||||
record ProjectResult(string PackageId, string Version);
|
||||
record ProjectResult(string PackageId, string Version, string RepoOwner);
|
||||
static async Task<Result<ProjectResult, ReadableError>> PrepareProject(RunContext rctx, StatusContext ctx) {
|
||||
ctx.Status = "Locating project file";
|
||||
if (!ProjectFile.TryLoad(Environment.CurrentDirectory, out var projectFile, out var error))
|
||||
@@ -124,6 +123,7 @@ public static class Program {
|
||||
|
||||
string packageId = projectFile.GetPackageId();
|
||||
string version;
|
||||
string repoOwner;
|
||||
|
||||
try {
|
||||
projectFile.Backup();
|
||||
@@ -161,8 +161,8 @@ public static class Program {
|
||||
ctx.Status = "Updating version";
|
||||
version = projectFile.GetVersion();
|
||||
version = ProjectFile.ChangeVersion(version, delta, rctx.Args.Target ?? IncrementTarget.Patch).Unwrap(rctx);
|
||||
|
||||
projectFile.SetVersion(version);
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
@@ -170,6 +170,8 @@ public static class Program {
|
||||
}
|
||||
|
||||
version = projectFile.GetVersion();
|
||||
repoOwner = projectFile.GetRepositoryOwner();
|
||||
|
||||
|
||||
if (!rctx.Args.Flags.ContainsKey("--simulate")) {
|
||||
try {
|
||||
@@ -221,7 +223,7 @@ public static class Program {
|
||||
}
|
||||
|
||||
projectFile.Save();
|
||||
return new Ok<ProjectResult>(new ProjectResult(packageId, version));
|
||||
return new Ok<ProjectResult>(new ProjectResult(packageId, version, repoOwner));
|
||||
}
|
||||
|
||||
static async Task<Result<Success, ReadableError>> PackProject(RunContext rctx, StatusContext ctx) {
|
||||
@@ -242,6 +244,7 @@ public static class Program {
|
||||
enum DestinationType {
|
||||
Local,
|
||||
Github,
|
||||
Main,
|
||||
Cloud
|
||||
}
|
||||
|
||||
@@ -286,7 +289,10 @@ public static class Program {
|
||||
destType = DestinationType.Cloud;
|
||||
} else if (dest == "github") {
|
||||
destType = DestinationType.Github;
|
||||
} else {
|
||||
} else if (dest == "main") {
|
||||
destType = DestinationType.Main;
|
||||
}
|
||||
else {
|
||||
lock(rctx) {
|
||||
ShowError(string.Format(Exceptions.destination_unrecognizable, dest));
|
||||
ShowHelp();
|
||||
@@ -298,16 +304,20 @@ public static class Program {
|
||||
var dctx = new DestinationContext(task, ctx, reader, pkg.FileInfo, destType switch {
|
||||
DestinationType.Cloud => dest["cloud-".Length..],
|
||||
DestinationType.Github => dest["github".Length..],
|
||||
DestinationType.Main => dest["main".Length..],
|
||||
DestinationType.Local => dest["local-".Length..]
|
||||
}, BufferSize, pkg.Size());
|
||||
|
||||
IDestination destination = destType switch {
|
||||
DestinationType.Local => new LocalDestination(dctx),
|
||||
DestinationType.Github => new GithubDestination(dctx, rctx.Args.Verbose),
|
||||
DestinationType.Cloud => new CloudDestiantion(dctx),
|
||||
Result<IDestination, ReadableError> destinationResult = destType switch {
|
||||
DestinationType.Local => new LocalDestination(dctx).Ok<IDestination>(),
|
||||
DestinationType.Github => GitDestination.CreateForGithub(dctx, project.RepoOwner, rctx.Args.Verbose).UpcastSuccess<GitDestination, IDestination, ReadableError>(),
|
||||
DestinationType.Main => GitDestination.CreateForGitea(dctx, project.RepoOwner, rctx.Args.Verbose).UpcastSuccess<GitDestination, IDestination, ReadableError>(),
|
||||
DestinationType.Cloud => new CloudDestiantion(dctx).Ok<IDestination>(),
|
||||
_ => throw new UnreachableException()
|
||||
};
|
||||
|
||||
var destination = destinationResult.Unwrap(rctx);
|
||||
|
||||
var result = await destination.WaitForCompletion(ct);
|
||||
lock(rctx) {
|
||||
if (result.Unwrap(rctx) is not null) {
|
||||
|
||||
@@ -114,6 +114,7 @@ internal class ProjectFile {
|
||||
set("PackageProjectUrl", "", required: false);
|
||||
set("RepositoryUrl", "", required: true);
|
||||
set("PackageId", "", required: true);
|
||||
set("RepositoryOwner", "", required: true);
|
||||
|
||||
if (failed.Count > 0) {
|
||||
error = string.Format(Exceptions.project_file_irreparable, Path, string.Join(", ", failed));
|
||||
@@ -124,6 +125,10 @@ internal class ProjectFile {
|
||||
return true;
|
||||
}
|
||||
|
||||
public string GetRepositoryOwner() {
|
||||
return MainPropertyGroup.GetProperty("RepositoryOwner");
|
||||
}
|
||||
|
||||
public List<PackageReference> GetPackageReferences() {
|
||||
return Project.ItemGroups
|
||||
.SelectMany(g => g.Items)
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generated by TARGET FORGE — MSBuild publish target -->
|
||||
<!-- Save as PublishAll.targets and <Import Project="PublishAll.targets" /> in your .csproj, -->
|
||||
<!-- or paste the <Target> below directly into the .csproj. -->
|
||||
<!-- Run: dotnet msbuild -t:PublishAll -->
|
||||
<Project>
|
||||
|
||||
<Target Name="PublishAll">
|
||||
<ItemGroup>
|
||||
<Rid Include="win-x64;linux-x64;osx-x64;osx-arm64" />
|
||||
</ItemGroup>
|
||||
|
||||
<MSBuild Projects="$(MSBuildProjectFullPath)"
|
||||
Targets="Publish"
|
||||
BuildInParallel="true"
|
||||
Properties="Configuration=Release;
|
||||
Platform=Any CPU;
|
||||
TargetFramework=net11.0;
|
||||
RuntimeIdentifier=%(Rid.Identity);
|
||||
SelfContained=true;
|
||||
PublishSingleFile=true;
|
||||
PublishDir=bin\Release\publish\%(Rid.Identity)\" />
|
||||
</Target>
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- All four are overridable from the CLI: -p:ArchiveVersion=1.2.3 etc. -->
|
||||
<ArchiveAppName Condition="'$(ArchiveAppName)' == ''">$(AssemblyName)</ArchiveAppName>
|
||||
<ArchiveVersion Condition="'$(ArchiveVersion)' == ''">$(Version)</ArchiveVersion>
|
||||
<ArchiveVersion Condition="'$(ArchiveVersion)' == ''">1.3.0</ArchiveVersion>
|
||||
<ArchiveOutputDir Condition="'$(ArchiveOutputDir)' == ''">$(MSBuildProjectDirectory)\dist\</ArchiveOutputDir>
|
||||
<PublishBaseDir Condition="'$(PublishBaseDir)' == ''">$(MSBuildProjectDirectory)\bin\Release\publish\</PublishBaseDir>
|
||||
</PropertyGroup>
|
||||
|
||||
<Target Name="Archive" DependsOnTargets="PublishAll">
|
||||
<MakeDir Directories="$(ArchiveOutputDir)" />
|
||||
|
||||
<ZipDirectory SourceDirectory="$(PublishBaseDir)%(Rid.Identity)\"
|
||||
DestinationFile="$(ArchiveOutputDir)$(ArchiveAppName)-$(ArchiveVersion)-%(Rid.Identity).zip"
|
||||
Overwrite="true" />
|
||||
|
||||
<Exec Command='tar -czf "$(ArchiveOutputDir)$(ArchiveAppName)-$(ArchiveVersion)-%(Rid.Identity).tar.gz" -C "$(PublishBaseDir)%(Rid.Identity)" .' />
|
||||
|
||||
<Message Importance="high" Text="Archived $(ArchiveAppName) $(ArchiveVersion) → $(ArchiveOutputDir)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
@@ -28,10 +28,36 @@ internal static class ResultExtensions {
|
||||
public static async Task<T> Unwrap<T>(this Task<Result<T, ReadableError>> result, Program.RunContext? rctx = null) {
|
||||
return (await result).Unwrap(rctx);
|
||||
}
|
||||
|
||||
public static Result<TTo, ETo> Cast<TFrom, EFrom, TTo, ETo>(this Result<TFrom, EFrom> result) where TTo : notnull, TFrom where ETo: notnull, EFrom {
|
||||
return result switch {
|
||||
TFrom tfrom => ((TTo)tfrom).Ok(),
|
||||
EFrom efrom => ((ETo)efrom),
|
||||
_ => throw new UnreachableException()
|
||||
};
|
||||
}
|
||||
|
||||
public static Result<TTo, ETo> Upcast<TFrom, EFrom, TTo, ETo>(this Result<TFrom, EFrom> result)
|
||||
where TFrom : TTo
|
||||
where EFrom : ETo
|
||||
{
|
||||
return result switch {
|
||||
TFrom tfrom => ((TTo)tfrom).Ok(), // Foo -> IFoo, implicit upcast, can't throw
|
||||
EFrom efrom => ((ETo)efrom),
|
||||
_ => throw new UnreachableException()
|
||||
};
|
||||
}
|
||||
|
||||
public static Result<TTo, E> CastSuccess<TFrom, TTo, E>(this Result<TFrom, E> result) where TTo : notnull, TFrom where E: notnull
|
||||
=> Cast<TFrom, E, TTo, E>(result);
|
||||
|
||||
public static Result<TTo, E> UpcastSuccess<TFrom, TTo, E>(this Result<TFrom, E> result) where TFrom : notnull, TTo where E: notnull
|
||||
=> Upcast<TFrom, E, TTo, E>(result);
|
||||
}
|
||||
|
||||
internal static class ObjectExtensions {
|
||||
public static Ok<T> Ok<T>(this T any) {
|
||||
return new Ok<T>(any);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="PublishAll.targets" />
|
||||
|
||||
<PropertyGroup>
|
||||
<RuntimeIdentifiers>win-x64;linux-x64;osx-arm64;osx-x64</RuntimeIdentifiers>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<TargetFramework>net11.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>preview</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="aeqw89.xml.ProjectFile" Version="1.0.3" />
|
||||
<PackageReference Include="aeqw89.xml.ProjectFile" Version="2.0.0" />
|
||||
<PackageReference Include="Aigamo.ResXGenerator" Version="4.3.0">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
||||
Reference in New Issue
Block a user