readonly record struct CommitLink(

This commit is contained in:
M-L-Ml 2025-04-21 20:50:23 +02:00
parent 46ae4064f9
commit f381c1cfdb
3 changed files with 78 additions and 84 deletions

View file

@ -8,75 +8,68 @@ namespace SourceGit.Models
/// <summary> /// <summary>
/// Represents a commit link for a remote repository. /// Represents a commit link for a remote repository.
/// </summary> /// </summary>
public class CommitLink public readonly record struct CommitLink(string Name, string URLPrefix)
{ {
public string Name { get; set; } }
public string URLPrefix { get; set; } public readonly record struct ProviderInfo(
string Name,
public CommitLink(string name, string prefix) string HostPrefix,
Func<string, string> ExtractRepo,
Func<string, string> BuildCommitUrlPrefix)
{
public bool IsMatch(string url) => url.StartsWith(HostPrefix, StringComparison.Ordinal);
}
public static class CommitLinkDetails // Changed from private to internal to fix CS1527
{
static readonly ProviderInfo[] Providers = new[]
{ {
Name = name; new ProviderInfo(
URLPrefix = prefix; "Github",
} "https://github.com/",
url => url.EndsWith(".git") ? url[19..^4] : url[19..],
public readonly record struct ProviderInfo( baseUrl => $"{baseUrl}/commit/"
string Name, ),
string HostPrefix, new ProviderInfo(
Func<string, string> ExtractRepo, "GitLab",
Func<string, string> BuildCommitUrlPrefix) "https://gitlab.",
{ url => {
public bool IsMatch(string url) => url.StartsWith(HostPrefix, StringComparison.Ordinal); var trimmed = url.EndsWith(".git") ? url[15..^4] : url[15..];
} int idx = trimmed.IndexOf('/') + 1;
return trimmed[idx..];
private static readonly ProviderInfo[] Providers = new[] },
{ baseUrl => $"{baseUrl}/-/commit/"
new ProviderInfo( ),
"Github", new ProviderInfo(
"https://github.com/", "Gitee",
url => url.EndsWith(".git") ? url[19..^4] : url[19..], "https://gitee.com/",
baseUrl => $"{baseUrl}/commit/" url => url.EndsWith(".git") ? url[18..^4] : url[18..],
), baseUrl => $"{baseUrl}/commit/"
new ProviderInfo( ),
"GitLab", new ProviderInfo(
"https://gitlab.", "BitBucket",
url => { "https://bitbucket.org/",
var trimmed = url.EndsWith(".git") ? url[15..^4] : url[15..]; url => url.EndsWith(".git") ? url[22..^4] : url[22..],
int idx = trimmed.IndexOf('/') + 1; baseUrl => $"{baseUrl}/commits/"
return trimmed[idx..]; ),
}, new ProviderInfo(
baseUrl => $"{baseUrl}/-/commit/" "Codeberg",
), "https://codeberg.org/",
new ProviderInfo( url => url.EndsWith(".git") ? url[21..^4] : url[21..],
"Gitee", baseUrl => $"{baseUrl}/commit/"
"https://gitee.com/", ),
url => url.EndsWith(".git") ? url[18..^4] : url[18..], new ProviderInfo(
baseUrl => $"{baseUrl}/commit/" "Gitea",
), "https://gitea.org/",
new ProviderInfo( url => url.EndsWith(".git") ? url[18..^4] : url[18..],
"BitBucket", baseUrl => $"{baseUrl}/commit/"
"https://bitbucket.org/", ),
url => url.EndsWith(".git") ? url[22..^4] : url[22..], new ProviderInfo(
baseUrl => $"{baseUrl}/commits/" "sourcehut",
), "https://git.sr.ht/",
new ProviderInfo( url => url.EndsWith(".git") ? url[18..^4] : url[18..],
"Codeberg", baseUrl => $"{baseUrl}/commit/"
"https://codeberg.org/", )
url => url.EndsWith(".git") ? url[21..^4] : url[21..], };
baseUrl => $"{baseUrl}/commit/"
),
new ProviderInfo(
"Gitea",
"https://gitea.org/",
url => url.EndsWith(".git") ? url[18..^4] : url[18..],
baseUrl => $"{baseUrl}/commit/"
),
new ProviderInfo(
"sourcehut",
"https://git.sr.ht/",
url => url.EndsWith(".git") ? url[18..^4] : url[18..],
baseUrl => $"{baseUrl}/commit/"
)
};
/// <summary> /// <summary>
/// Attempts to create a CommitLink for a given remote by matching a provider. /// Attempts to create a CommitLink for a given remote by matching a provider.
@ -97,7 +90,7 @@ namespace SourceGit.Models
/// </summary> /// </summary>
public static List<CommitLink> Get(List<Remote> remotes) public static List<CommitLink> Get(List<Remote> remotes)
{ {
return remotes.Select(remote => return remotes.Select(static remote =>
{ {
var rr = TryCreateCommitLink(remote); var rr = TryCreateCommitLink(remote);
@ -111,7 +104,8 @@ namespace SourceGit.Models
} }
#endif #endif
return rr; return rr;
}).Where(cl => cl != null).ToList(); }).Select(cl => cl.Value) // Convert nullable CommitLink to non-nullable CommitLink
.Where(cl => cl != null).ToList();
} }
#if DEBUG #if DEBUG
@ -144,7 +138,7 @@ namespace SourceGit.Models
return outs.FirstOrDefault(); return outs.FirstOrDefault();
} }
static CommitLink() static CommitLinkDetails()
{ {
//Unit tests , TODO: make normal UnitTests, delete this code. //Unit tests , TODO: make normal UnitTests, delete this code.

View file

@ -134,7 +134,7 @@ namespace SourceGit.ViewModels
public CommitDetail(Repository repo) public CommitDetail(Repository repo)
{ {
_repo = repo; _repo = repo;
WebLinks = Models.CommitLink.Get(repo.Remotes); WebLinks = Models.CommitLinkDetails.Get(repo.Remotes);
} }
public void Cleanup() public void Cleanup()

View file

@ -37,7 +37,7 @@ namespace SourceGit.Views
get => GetValue(SupportsContainsInProperty); get => GetValue(SupportsContainsInProperty);
set => SetValue(SupportsContainsInProperty, value); set => SetValue(SupportsContainsInProperty, value);
} }
//TODO: Maybe some observable container instead List? Add a comment for explanation.
public static readonly StyledProperty<List<Models.CommitLink>> WebLinksProperty = public static readonly StyledProperty<List<Models.CommitLink>> WebLinksProperty =
AvaloniaProperty.Register<CommitBaseInfo, List<Models.CommitLink>>(nameof(WebLinks)); AvaloniaProperty.Register<CommitBaseInfo, List<Models.CommitLink>>(nameof(WebLinks));