mirror of
https://github.com/par274/sharpemu.git
synced 2026-07-19 17:36:15 +08:00
More logger improvements (#58)
* fix * fix --------- Co-authored-by: j92580498-max <j92580498-max@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
// Copyright (C) 2026 SharpEmu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
namespace SharpEmu.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// Build provenance for the running emulator, populated at compile time from
|
||||
/// GitHub Actions environment variables via <c>[AssemblyMetadata]</c> and
|
||||
/// surfaced as a touchHLE-style banner at the top of the log.
|
||||
/// </summary>
|
||||
public static class BuildInfo
|
||||
{
|
||||
private const string ProjectUrl = "https://github.com/par274/sharpemu";
|
||||
private const string CanonicalRepository = "par274/sharpemu";
|
||||
|
||||
/// <summary>Short commit hash the build was produced from, or <c>null</c>.</summary>
|
||||
public static string? CommitSha { get; }
|
||||
|
||||
/// <summary>Branch the build was produced from, or <c>null</c>.</summary>
|
||||
public static string? Branch { get; }
|
||||
|
||||
/// <summary>Repository slug (<c>owner/name</c>) the build came from, or <c>null</c>.</summary>
|
||||
public static string? Repository { get; }
|
||||
|
||||
/// <summary>URL of the GitHub Actions workflow run that produced the build, or <c>null</c>.</summary>
|
||||
public static string? WorkflowRunUrl { get; }
|
||||
|
||||
/// <summary>Build configuration (e.g. <c>Debug</c> or <c>Release</c>), or <c>null</c>.</summary>
|
||||
public static string? Configuration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether this build is an official release: a Release-configuration CI build
|
||||
/// from the canonical repository, produced by a push to <c>main</c> or a manual
|
||||
/// workflow dispatch (matching the CI <c>release</c> job). All other builds
|
||||
/// (pull requests, forks, feature branches, and local/Debug builds) are
|
||||
/// considered unofficial.
|
||||
/// </summary>
|
||||
public static bool IsOfficialRelease { get; }
|
||||
|
||||
static BuildInfo()
|
||||
{
|
||||
var metadata = ReadMetadata();
|
||||
|
||||
CommitSha = Normalize(metadata.GetValueOrDefault("SharpEmu.BuildSha"));
|
||||
if (CommitSha is { Length: > 7 })
|
||||
{
|
||||
CommitSha = CommitSha[..7];
|
||||
}
|
||||
|
||||
Branch = Normalize(metadata.GetValueOrDefault("SharpEmu.BuildBranch"));
|
||||
Repository = Normalize(metadata.GetValueOrDefault("SharpEmu.BuildRepository"));
|
||||
Configuration = Normalize(metadata.GetValueOrDefault("SharpEmu.BuildConfiguration"));
|
||||
|
||||
var serverUrl = Normalize(metadata.GetValueOrDefault("SharpEmu.BuildServerUrl"));
|
||||
var runId = Normalize(metadata.GetValueOrDefault("SharpEmu.BuildRunId"));
|
||||
if (serverUrl is not null && Repository is not null && runId is not null)
|
||||
{
|
||||
WorkflowRunUrl = $"{serverUrl.TrimEnd('/')}/{Repository}/actions/runs/{runId}";
|
||||
}
|
||||
|
||||
var eventName = Normalize(metadata.GetValueOrDefault("SharpEmu.BuildEventName"));
|
||||
var gitRef = Normalize(metadata.GetValueOrDefault("SharpEmu.BuildRef"));
|
||||
|
||||
var isReleaseConfig = string.Equals(Configuration, "Release", StringComparison.OrdinalIgnoreCase);
|
||||
var isCanonicalRepo = string.Equals(Repository, CanonicalRepository, StringComparison.OrdinalIgnoreCase);
|
||||
var isReleaseTrigger =
|
||||
string.Equals(eventName, "workflow_dispatch", StringComparison.OrdinalIgnoreCase) ||
|
||||
(string.Equals(eventName, "push", StringComparison.OrdinalIgnoreCase) &&
|
||||
string.Equals(gitRef, "refs/heads/main", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
IsOfficialRelease = isReleaseConfig && isCanonicalRepo && isReleaseTrigger && CommitSha is not null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The multi-line banner, e.g.
|
||||
/// <code>
|
||||
/// SharpEmu UNOFFICIAL f11ac59 — https://github.com/par274/sharpemu
|
||||
///
|
||||
/// Built from branch "main" of "par274/sharpemu" by GitHub Actions workflow run https://github.com/par274/sharpemu/actions/runs/123.
|
||||
/// </code>
|
||||
/// Official release builds drop the <c>UNOFFICIAL</c> tag. Falls back to a
|
||||
/// local-build line when no CI provenance is present.
|
||||
/// </summary>
|
||||
public static string Banner
|
||||
{
|
||||
get
|
||||
{
|
||||
string version;
|
||||
if (CommitSha is null)
|
||||
{
|
||||
version = "UNOFFICIAL";
|
||||
}
|
||||
else if (IsOfficialRelease)
|
||||
{
|
||||
version = CommitSha;
|
||||
}
|
||||
else
|
||||
{
|
||||
version = $"UNOFFICIAL {CommitSha}";
|
||||
}
|
||||
|
||||
var header = $"SharpEmu {version} — {ProjectUrl}";
|
||||
|
||||
if (Branch is null || Repository is null || WorkflowRunUrl is null)
|
||||
{
|
||||
return $"{header}{Environment.NewLine}{Environment.NewLine}Local build (not produced by CI).";
|
||||
}
|
||||
|
||||
return $"{header}{Environment.NewLine}{Environment.NewLine}" +
|
||||
$"Built from branch \"{Branch}\" of \"{Repository}\" by GitHub Actions workflow run {WorkflowRunUrl}.";
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> ReadMetadata()
|
||||
{
|
||||
var result = new Dictionary<string, string>(StringComparer.Ordinal);
|
||||
var assemblies = new[] { Assembly.GetEntryAssembly(), typeof(BuildInfo).Assembly };
|
||||
|
||||
foreach (var assembly in assemblies)
|
||||
{
|
||||
if (assembly is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var attribute in assembly.GetCustomAttributes<AssemblyMetadataAttribute>())
|
||||
{
|
||||
if (attribute.Key.StartsWith("SharpEmu.Build", StringComparison.Ordinal) &&
|
||||
!result.ContainsKey(attribute.Key) &&
|
||||
attribute.Value is not null)
|
||||
{
|
||||
result[attribute.Key] = attribute.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string? Normalize(string? value) =>
|
||||
string.IsNullOrWhiteSpace(value) ? null : value.Trim();
|
||||
}
|
||||
Reference in New Issue
Block a user