From e474fa63e864b148ba3acf51dc2c3f4ee0622c3d Mon Sep 17 00:00:00 2001 From: devlooped-bot Date: Mon, 12 Aug 2024 19:46:07 +0000 Subject: [PATCH] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Bump=20files=20with=20dotn?= =?UTF-8?q?et-file=20sync=20#=20devlooped/oss?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - We don't push just from ubuntu anymore https://github.com/devlooped/oss/commit/7ec9101 # devlooped/SponsorLink - Add distinct diagnostic for contributors https://github.com/devlooped/SponsorLink/commit/ca82a9d - Switch to public v1 of dotnet-ilrepack https://github.com/devlooped/SponsorLink/commit/3845393 - Apply formatting https://github.com/devlooped/SponsorLink/commit/d5300a8 --- .github/workflows/build.yml | 1 - .netconfig | 45 +++-- src/SponsorLink/SponsorLink.Analyzer.targets | 2 +- .../SponsorLink/DiagnosticsManager.cs | 100 ++++++---- .../SponsorLink/Resources.es-AR.resx | 172 ++++++++++++++++++ src/SponsorLink/SponsorLink/Resources.es.resx | 9 + src/SponsorLink/SponsorLink/Resources.resx | 9 + .../SponsorLink/SponsorLink.csproj | 4 +- .../SponsorLink/SponsorLinkAnalyzer.cs | 2 +- src/SponsorLink/SponsorLink/SponsorStatus.cs | 28 ++- src/SponsorLink/Tests/AnalyzerTests.cs | 30 ++- src/SponsorLink/Tests/Sample.cs | 17 +- 12 files changed, 346 insertions(+), 73 deletions(-) create mode 100644 src/SponsorLink/SponsorLink/Resources.es-AR.resx diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f4a9bc6d..648d55a4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -79,7 +79,6 @@ jobs: name: logs path: '*.binlog' - # Only push CI package to sleet feed if building on ubuntu (fastest) - name: 🚀 sleet env: SLEET_CONNECTION: ${{ secrets.SLEET_CONNECTION }} diff --git a/.netconfig b/.netconfig index 96dfd9c0..af3cd9c1 100644 --- a/.netconfig +++ b/.netconfig @@ -30,9 +30,9 @@ sha = 49661dbf0720cde93eb5569be7523b5912351560 [file ".github/workflows/build.yml"] url = https://github.com/devlooped/oss/blob/main/.github/workflows/build.yml - etag = ce104e9b04fe6a54b90cdfd3d5c02f2e902f8ac878b1d059edc1b6bed70872be + etag = 35b2a5b03c26cbe7522e30b2b987e04991e8ba18accd38b7ebd88191f1698c2d weak - sha = b5bb972199aa6ff220dda196588b23c21bb2780f + sha = 7ec91019eddb4fc7e0b09118538b256087f82e18 [file ".gitignore"] url = https://github.com/devlooped/oss/blob/main/.gitignore etag = a9c37ae312afac14b78436a7d018af4483d88736b5f780576f2c5a0b3f14998c @@ -191,8 +191,8 @@ weak [file "src/SponsorLink/SponsorLink/DiagnosticsManager.cs"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/SponsorLink/DiagnosticsManager.cs - sha = 8ce2ffb3e833da8f6809c9c7e7b7113fec2e3046 - etag = 3b597ea6c68c25727171bcdee45e0793268a3ec573f4c821b5ee92b776cba269 + sha = ca82a9d6298a933192c5dfd2c5881ebadb85d0fe + etag = 68901df18e599f2171229d39c0123629c0f37a641eac0381358732a25a63e422 weak [file "src/SponsorLink/SponsorLink/ManifestStatus.cs"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/SponsorLink/ManifestStatus.cs @@ -201,13 +201,13 @@ weak [file "src/SponsorLink/SponsorLink/Resources.es.resx"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/SponsorLink/Resources.es.resx - sha = f47528874a6d9192b5546f84b455f5ccc474a707 - etag = c0a05bb5efedf8e30a73ab96678579ad33832e4a4aec75d3b596b47f248c23f5 + sha = ca82a9d6298a933192c5dfd2c5881ebadb85d0fe + etag = 8a23a5fe14e9c415e5f3e9a53c496750c3369199424eb5080da1401a78245dc3 weak [file "src/SponsorLink/SponsorLink/Resources.resx"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/SponsorLink/Resources.resx - sha = f47528874a6d9192b5546f84b455f5ccc474a707 - etag = fcb46a86511cb7996e8dcd1f4e283cea9cd51610b094ac49a7396301730814b0 + sha = ca82a9d6298a933192c5dfd2c5881ebadb85d0fe + etag = e0e9e222dd9c5a0dbbefed4f5dd724a2a1e5ea55bea8d4428f06dc0d8d677487 weak [file "src/SponsorLink/SponsorLink/SponsorLink.cs"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/SponsorLink/SponsorLink.cs @@ -216,18 +216,18 @@ weak [file "src/SponsorLink/SponsorLink/SponsorLink.csproj"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/SponsorLink/SponsorLink.csproj - sha = f6fd85da07d1b52922fb48676d9aed9f1aef782b - etag = 8d1a33b152eddf3a662728e8420fc2385c82c9d80ae06a562b78a2432709f74a + sha = d5300a8c7cd8df9ce8ee0ef7714e17cfcc5d9454 + etag = 88652b0720f718ecedb3768b20b7a59bf38d635b3a1c2278c7603f99cc02b517 weak [file "src/SponsorLink/SponsorLink/SponsorLinkAnalyzer.cs"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/SponsorLink/SponsorLinkAnalyzer.cs - sha = d7090c1dbcb20c68b99486a6dc53d86b8d9b06bb - etag = 2a94a016b5dc9371dc16ed57852acb8570ee0e6f3076fd749e1235e56ed142a0 + sha = ca82a9d6298a933192c5dfd2c5881ebadb85d0fe + etag = 2b4bf43116b7bd745e0415248c94cdae63d8d241f326117c8bcb30d3700c0e46 weak [file "src/SponsorLink/SponsorLink/SponsorStatus.cs"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/SponsorLink/SponsorStatus.cs - sha = f47528874a6d9192b5546f84b455f5ccc474a707 - etag = a29e71737e91725deb450384379ff955dfab67bb0846e77b2c234dfb036d3f7a + sha = ca82a9d6298a933192c5dfd2c5881ebadb85d0fe + etag = cd51bb4f18ee3770aefc97312721f4787aa9161561a0125be71db4f3d8325f56 weak [file "src/SponsorLink/SponsorLink/SponsorableLib.targets"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/SponsorLink/SponsorableLib.targets @@ -261,8 +261,8 @@ weak [file "src/SponsorLink/Tests/AnalyzerTests.cs"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/Tests/AnalyzerTests.cs - sha = 2a5e198c982593da18b016161741c75846f67a71 - etag = 9a86f7482a4401a8dd30148976f47e2a98cb9cfe9c64153d336989146ce7b4b7 + sha = ca82a9d6298a933192c5dfd2c5881ebadb85d0fe + etag = f6a457be2066ea997e23380628b9dd75a207c8992604ad997521c6bbe99fe07a weak [file "src/SponsorLink/Tests/Attributes.cs"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/Tests/Attributes.cs @@ -286,8 +286,8 @@ weak [file "src/SponsorLink/Tests/Sample.cs"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/Tests/Sample.cs - sha = f47528874a6d9192b5546f84b455f5ccc474a707 - etag = 8d32d6b062061672f37acd9360cdeb0d5fc87e15f2f65f355c2a1ee98e8da21c + sha = ca82a9d6298a933192c5dfd2c5881ebadb85d0fe + etag = 1875555adb7eab21acf1e730b6baeb8c095d9f6f9f07303a87ad9c16e0f6490d weak [file "src/SponsorLink/Tests/SponsorLinkTests.cs"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/Tests/SponsorLinkTests.cs @@ -351,11 +351,16 @@ weak [file "src/SponsorLink/SponsorLink.Analyzer.targets"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/SponsorLink.Analyzer.targets - sha = f6fd85da07d1b52922fb48676d9aed9f1aef782b - etag = 83ea5d4afc0c0b4b10fda27927de6f9e441f877b01d2b3427f9e18a28285308b + sha = 3845393462f5a89f90e2c795345d9342bf87dbe2 + etag = 08e58ed40ea91fdbe1a798c623f1048955880575fb01e16bfd5003fc288b173b weak [file "src/SponsorLink/SponsorLink.Analyzer.Tests.targets"] url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/SponsorLink.Analyzer.Tests.targets sha = 058dbbc3582042d7fdcaf5741db59d2b46ea1222 etag = 2d8bac60892b5565e3419b1fa775c5b977af202304ef3c25a4c6d04c7ac9faf1 weak +[file "src/SponsorLink/SponsorLink/Resources.es-AR.resx"] + url = https://github.com/devlooped/SponsorLink/blob/main/samples/dotnet/SponsorLink/Resources.es-AR.resx + sha = ca82a9d6298a933192c5dfd2c5881ebadb85d0fe + etag = eeaafb2886bfb0d66e6e5aa751a60f3691433ac30fdd4bf5c14138dac7174ba9 + weak diff --git a/src/SponsorLink/SponsorLink.Analyzer.targets b/src/SponsorLink/SponsorLink.Analyzer.targets index 0eec8c98..53ed373a 100644 --- a/src/SponsorLink/SponsorLink.Analyzer.targets +++ b/src/SponsorLink/SponsorLink.Analyzer.targets @@ -139,7 +139,7 @@ partial class SponsorLink - diff --git a/src/SponsorLink/SponsorLink/DiagnosticsManager.cs b/src/SponsorLink/SponsorLink/DiagnosticsManager.cs index 764a1708..002cd182 100644 --- a/src/SponsorLink/SponsorLink/DiagnosticsManager.cs +++ b/src/SponsorLink/SponsorLink/DiagnosticsManager.cs @@ -8,6 +8,7 @@ using System.IO; using System.Linq; using Humanizer; +using Humanizer.Localisation; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using static Devlooped.Sponsors.SponsorLink; @@ -28,7 +29,12 @@ class DiagnosticsManager // // { SponsorStatus.Unknown, CreateUnknown([.. Sponsorables.Keys], Funding.Product, Funding.Prefix) }, - { SponsorStatus.Sponsor, CreateSponsor([.. Sponsorables.Keys], Funding.Prefix) }, + { SponsorStatus.User, CreateSponsor([.. Sponsorables.Keys], Funding.Prefix) }, + { SponsorStatus.Contributor, CreateContributor([.. Sponsorables.Keys], Funding.Prefix) }, + // NOTE: organization is a special case of sponsor, but we report it as hidden since the user isn't directly involved. + { SponsorStatus.Organization, CreateSponsor([.. Sponsorables.Keys], Funding.Prefix, hidden: true) }, + // NOTE: similar to organization, we don't show team membership in the IDE. + { SponsorStatus.Team, CreateContributor([.. Sponsorables.Keys], Funding.Prefix, hidden: true) }, { SponsorStatus.Expiring, CreateExpiring([.. Sponsorables.Keys], Funding.Prefix) }, { SponsorStatus.Expired, CreateExpired([.. Sponsorables.Keys], Funding.Prefix) }, }; @@ -88,13 +94,12 @@ public SponsorStatus GetOrSetStatus(Func options) /// /// Pushes a diagnostic for the given product. /// - /// The same diagnostic that was pushed, for chained invocations. - Diagnostic Push(Diagnostic diagnostic, string product = Funding.Product) + SponsorStatus Push(Diagnostic diagnostic, SponsorStatus status, string product = Funding.Product) { // We only expect to get one warning per sponsorable+product // combination, and first one to set wins. Diagnostics.TryAdd(product, diagnostic); - return diagnostic; + return status; } SponsorStatus GetOrSetStatus(Func> getAdditionalFiles, Func getGlobalOptions) @@ -122,18 +127,18 @@ SponsorStatus GetOrSetStatus(Func> getAdditionalF if (installed != default && ((DateTime.Now - installed).TotalDays <= Funding.Grace)) { // report unknown, either unparsed manifest or one with no expiration (which we never emit). - Push(Diagnostic.Create(KnownDescriptors[SponsorStatus.Unknown], null, + return Push(Diagnostic.Create(KnownDescriptors[SponsorStatus.Unknown], null, properties: ImmutableDictionary.Create().Add(nameof(SponsorStatus), nameof(SponsorStatus.Grace)), - Funding.Product, Sponsorables.Keys.Humanize(Resources.Or))); - return SponsorStatus.Grace; + Funding.Product, Sponsorables.Keys.Humanize(Resources.Or)), + SponsorStatus.Grace); } } // report unknown, either unparsed manifest or one with no expiration (which we never emit). - Push(Diagnostic.Create(KnownDescriptors[SponsorStatus.Unknown], null, + return Push(Diagnostic.Create(KnownDescriptors[SponsorStatus.Unknown], null, properties: ImmutableDictionary.Create().Add(nameof(SponsorStatus), nameof(SponsorStatus.Unknown)), - Funding.Product, Sponsorables.Keys.Humanize(Resources.Or))); - return SponsorStatus.Unknown; + Funding.Product, Sponsorables.Keys.Humanize(Resources.Or)), + SponsorStatus.Unknown); } else if (exp < DateTime.Now) { @@ -141,25 +146,37 @@ SponsorStatus GetOrSetStatus(Func> getAdditionalF if (exp.AddDays(Funding.Grace) < DateTime.Now) { // report expiring soon - Push(Diagnostic.Create(KnownDescriptors[SponsorStatus.Expiring], null, - properties: ImmutableDictionary.Create().Add(nameof(SponsorStatus), nameof(SponsorStatus.Expiring)))); - return SponsorStatus.Expiring; + return Push(Diagnostic.Create(KnownDescriptors[SponsorStatus.Expiring], null, + properties: ImmutableDictionary.Create().Add(nameof(SponsorStatus), nameof(SponsorStatus.Expiring))), + SponsorStatus.Expiring); } else { // report expired - Push(Diagnostic.Create(KnownDescriptors[SponsorStatus.Expired], null, - properties: ImmutableDictionary.Create().Add(nameof(SponsorStatus), nameof(SponsorStatus.Expired)))); - return SponsorStatus.Expired; + return Push(Diagnostic.Create(KnownDescriptors[SponsorStatus.Expired], null, + properties: ImmutableDictionary.Create().Add(nameof(SponsorStatus), nameof(SponsorStatus.Expired))), + SponsorStatus.Expired); } } else { - // report sponsor - Push(Diagnostic.Create(KnownDescriptors[SponsorStatus.Sponsor], null, - properties: ImmutableDictionary.Create().Add(nameof(SponsorStatus), nameof(SponsorStatus.Sponsor)), - Funding.Product)); - return SponsorStatus.Sponsor; + status = + claims.IsInRole("team") ? + SponsorStatus.Team : + claims.IsInRole("user") ? + SponsorStatus.User : + claims.IsInRole("contrib") ? + SponsorStatus.Contributor : + claims.IsInRole("org") ? + SponsorStatus.Organization : + SponsorStatus.Unknown; + + if (KnownDescriptors.TryGetValue(status, out var descriptor)) + return Push(Diagnostic.Create(descriptor, null, + properties: ImmutableDictionary.Create().Add(nameof(SponsorStatus), status.ToString()), + Funding.Product), status); + + return status; } } @@ -168,26 +185,15 @@ SponsorStatus GetOrSetStatus(Func> getAdditionalF { nameof(SponsorStatus.Grace) => SponsorStatus.Grace, nameof(SponsorStatus.Unknown) => SponsorStatus.Unknown, - nameof(SponsorStatus.Sponsor) => SponsorStatus.Sponsor, + nameof(SponsorStatus.User) => SponsorStatus.User, nameof(SponsorStatus.Expiring) => SponsorStatus.Expiring, nameof(SponsorStatus.Expired) => SponsorStatus.Expired, _ => null, } : null; - internal static DiagnosticDescriptor CreateSponsor(string[] sponsorable, string prefix) => new( - $"{prefix}100", - Resources.Sponsor_Title, - Resources.Sponsor_Message, - "SponsorLink", - DiagnosticSeverity.Info, - isEnabledByDefault: true, - description: Resources.Sponsor_Description, - helpLinkUri: "https://github.com/devlooped#sponsorlink", - "DoesNotSupportF1Help"); - internal static DiagnosticDescriptor CreateUnknown(string[] sponsorable, string product, string prefix) => new( - $"{prefix}101", + $"{prefix}100", Resources.Unknown_Title, Resources.Unknown_Message, "SponsorLink", @@ -200,7 +206,7 @@ SponsorStatus GetOrSetStatus(Func> getAdditionalF WellKnownDiagnosticTags.NotConfigurable); internal static DiagnosticDescriptor CreateExpiring(string[] sponsorable, string prefix) => new( - $"{prefix}103", + $"{prefix}101", Resources.Expiring_Title, Resources.Expiring_Message, "SponsorLink", @@ -211,7 +217,7 @@ SponsorStatus GetOrSetStatus(Func> getAdditionalF "DoesNotSupportF1Help", WellKnownDiagnosticTags.NotConfigurable); internal static DiagnosticDescriptor CreateExpired(string[] sponsorable, string prefix) => new( - $"{prefix}104", + $"{prefix}102", Resources.Expired_Title, Resources.Expired_Message, "SponsorLink", @@ -220,4 +226,26 @@ SponsorStatus GetOrSetStatus(Func> getAdditionalF description: string.Format(CultureInfo.CurrentCulture, Resources.Expired_Description, string.Join(" ", sponsorable)), helpLinkUri: "https://github.com/devlooped#autosync", "DoesNotSupportF1Help", WellKnownDiagnosticTags.NotConfigurable); + + internal static DiagnosticDescriptor CreateSponsor(string[] sponsorable, string prefix, bool hidden = false) => new( + $"{prefix}105", + Resources.Sponsor_Title, + Resources.Sponsor_Message, + "SponsorLink", + hidden ? DiagnosticSeverity.Hidden : DiagnosticSeverity.Info, + isEnabledByDefault: true, + description: Resources.Sponsor_Description, + helpLinkUri: "https://github.com/devlooped#sponsorlink", + "DoesNotSupportF1Help"); + + internal static DiagnosticDescriptor CreateContributor(string[] sponsorable, string prefix, bool hidden = false) => new( + $"{prefix}106", + Resources.Contributor_Title, + Resources.Contributor_Message, + "SponsorLink", + hidden ? DiagnosticSeverity.Hidden : DiagnosticSeverity.Info, + isEnabledByDefault: true, + description: Resources.Contributor_Description, + helpLinkUri: "https://github.com/devlooped#sponsorlink", + "DoesNotSupportF1Help"); } diff --git a/src/SponsorLink/SponsorLink/Resources.es-AR.resx b/src/SponsorLink/SponsorLink/Resources.es-AR.resx new file mode 100644 index 00000000..42c5bbbe --- /dev/null +++ b/src/SponsorLink/SponsorLink/Resources.es-AR.resx @@ -0,0 +1,172 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Patrocinar los proyectos en que dependés asegura que se mantengan activos, y que recibas el apoyo que necesitás. También es muy económico y está disponible en todo el mundo! +Por favor considerá apoyar el proyecto patrocinando en {0} y ejecutando posteriormente 'sponsor sync {1}'. + + + Por favor considerá apoyar {0} patrocinando @{1} 🙏 + + + Estado de patrocinio desconocido + + + Funcionalidades exclusivas para patrocinadores pueden no estar disponibles. Ejecutá 'sponsor sync {0}' y, opcionalmente, habilita la sincronización automática. + + + El estado de patrocino ha expirado y la sincronización automática no está habilitada. + + + El estado de patrocino ha expirado + + + Sos un verdadero héroe. Tu patrocinio ayuda a mantener el proyecto vivo y próspero 🙏. + + + Gracias por apoyar a {0} con tu patrocinio 💟! + + + Sos un patrocinador del proyecto, sos lo máximo 💟! + + + El estado de patrocino ha expirado y estás en un período de gracia. Ejecutá 'sponsor sync {0}' y, opcionalmente, habilitá la sincronización automática. + + + El estado de patrocino necesita actualización periódica y la sincronización automática no está habilitada. + + + El estado de patrocino ha expirado y el período de gracia terminará pronto + + + y + + + o + + + Gracias por ser parte del equipo por tu contribución 🙏. + + + Gracias por ser parte del equipo {0} con tu contribución 💟! + + + Sos un contribuidor al proyecto, sos groso 💟! + + \ No newline at end of file diff --git a/src/SponsorLink/SponsorLink/Resources.es.resx b/src/SponsorLink/SponsorLink/Resources.es.resx index ec1b5c1f..7c82c52f 100644 --- a/src/SponsorLink/SponsorLink/Resources.es.resx +++ b/src/SponsorLink/SponsorLink/Resources.es.resx @@ -160,4 +160,13 @@ Por favor considera apoyar el proyecto patrocinando en {0} y ejecutando posterio o + + Gracias por ser parte del equipo por tu contribución 🙏. + + + Gracias por ser parte del equipo {0} con tu contribución 💟! + + + Eres un contribuidor al proyecto, eres lo máximo 💟! + \ No newline at end of file diff --git a/src/SponsorLink/SponsorLink/Resources.resx b/src/SponsorLink/SponsorLink/Resources.resx index e12a0e55..0e355997 100644 --- a/src/SponsorLink/SponsorLink/Resources.resx +++ b/src/SponsorLink/SponsorLink/Resources.resx @@ -161,4 +161,13 @@ Please consider supporting the project by sponsoring at {0} and running 'sponsor or + + Thanks for being part of the team with your contributions 🙏. + + + Thank you for being part of team {0} with your contributions 💟! + + + You are a contributor to the project, you rock 💟! + \ No newline at end of file diff --git a/src/SponsorLink/SponsorLink/SponsorLink.csproj b/src/SponsorLink/SponsorLink/SponsorLink.csproj index 7cc9ee75..d3c0cc2b 100644 --- a/src/SponsorLink/SponsorLink/SponsorLink.csproj +++ b/src/SponsorLink/SponsorLink/SponsorLink.csproj @@ -30,6 +30,7 @@ + @@ -39,8 +40,7 @@ - + $(FundingProduct) diff --git a/src/SponsorLink/SponsorLink/SponsorLinkAnalyzer.cs b/src/SponsorLink/SponsorLink/SponsorLinkAnalyzer.cs index 3f7decda..1a097505 100644 --- a/src/SponsorLink/SponsorLink/SponsorLinkAnalyzer.cs +++ b/src/SponsorLink/SponsorLink/SponsorLinkAnalyzer.cs @@ -44,7 +44,7 @@ public override void Initialize(AnalysisContext context) ctx.RegisterCompilationEndAction(ctx => { // We'd never report Info/hero link if users opted out of it. - if (status == SponsorStatus.Sponsor && + if (status.IsSponsor() && ctx.Options.AnalyzerConfigOptionsProvider.GlobalOptions.TryGetValue("build_property.SponsorLinkHero", out var slHero) && bool.TryParse(slHero, out var isHero) && isHero) return; diff --git a/src/SponsorLink/SponsorLink/SponsorStatus.cs b/src/SponsorLink/SponsorLink/SponsorStatus.cs index 97b344e4..b78734ce 100644 --- a/src/SponsorLink/SponsorLink/SponsorStatus.cs +++ b/src/SponsorLink/SponsorLink/SponsorStatus.cs @@ -1,6 +1,18 @@ // namespace Devlooped.Sponsors; +public static class SponsorStatusExtensions +{ + /// + /// Whether represents a sponsor (directly or indirectly). + /// + public static bool IsSponsor(this SponsorStatus status) + => status == SponsorStatus.User || + status == SponsorStatus.Team || + status == SponsorStatus.Contributor || + status == SponsorStatus.Organization; +} + /// /// The determined sponsoring status. /// @@ -23,7 +35,19 @@ public enum SponsorStatus /// Expired, /// - /// The user is sponsoring. + /// The user is personally sponsoring. + /// + User, + /// + /// The user is a team member. + /// + Team, + /// + /// The user is a contributor. + /// + Contributor, + /// + /// The user is a member of a contributing organization. /// - Sponsor, + Organization } diff --git a/src/SponsorLink/Tests/AnalyzerTests.cs b/src/SponsorLink/Tests/AnalyzerTests.cs index dc9ed215..7d0d7b12 100644 --- a/src/SponsorLink/Tests/AnalyzerTests.cs +++ b/src/SponsorLink/Tests/AnalyzerTests.cs @@ -2,9 +2,11 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Data; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.CompilerServices; +using System.Security.Claims; using System.Text; using System.Threading.Tasks; using Analyzer::Devlooped.Sponsors; @@ -145,10 +147,22 @@ public async Task WhenUnknownAndGraceExpired_ThenReportsUnknown() Assert.Equal(SponsorStatus.Unknown, status); } - [Fact] - public async Task WhenSponsoring_ThenReportsSponsor() + [Theory] + [InlineData("user", SponsorStatus.User)] + [InlineData("org", SponsorStatus.Organization)] + [InlineData("contrib", SponsorStatus.Contributor)] + [InlineData("team", SponsorStatus.Team)] + // team trumps everything (since team members will typically also be contributors) + [InlineData("user,contrib,team", SponsorStatus.Team)] + // user trumps others + [InlineData("user,org,contrib", SponsorStatus.User)] + // contrib trumps org + [InlineData("org,contrib", SponsorStatus.Contributor)] + // team trumps contrib (since team members will typically also be contributors + [InlineData("contrib,team", SponsorStatus.Team)] + public async Task WhenSponsoringRole_ThenEnsureStatus(string roles, SponsorStatus status) { - var sponsor = sponsorable.Sign([], expiration: TimeSpan.FromMinutes(5)); + var sponsor = sponsorable.Sign(roles.Split(',').Select(x => new Claim("roles", x)), expiration: TimeSpan.FromMinutes(5)); var jwt = Path.Combine(GetTempPath(), "kzu.jwt"); File.WriteAllText(jwt, sponsor, Encoding.UTF8); @@ -167,17 +181,21 @@ public async Task WhenSponsoring_ThenReportsSponsor() var diagnostic = diagnostics.Single(x => x.Properties.TryGetValue(nameof(SponsorStatus), out var value)); Assert.True(diagnostic.Properties.TryGetValue(nameof(SponsorStatus), out var value)); - var status = Enum.Parse(value); + var actual = Enum.Parse(value); - Assert.Equal(SponsorStatus.Sponsor, status); + Assert.Equal(status, actual); } [Fact] public async Task WhenMultipleAnalyzers_ThenReportsOnce() { + var sponsor = sponsorable.Sign([new("roles", "user")], expiration: TimeSpan.FromMinutes(5)); + var jwt = Path.Combine(GetTempPath(), "kzu.jwt"); + File.WriteAllText(jwt, sponsor, Encoding.UTF8); + var compilation = CSharpCompilation.Create("test", [CSharpSyntaxTree.ParseText("//")]) .WithAnalyzers([new SponsorLinkAnalyzer(), new SponsorLinkAnalyzer()], - new AnalyzerOptions([], new TestAnalyzerConfigOptionsProvider(new()) + new AnalyzerOptions([new AdditionalTextFile(jwt)], new TestAnalyzerConfigOptionsProvider(new()) { // Force reporting without wait period { "build_property.SponsorLinkNoInstallGrace", "true" }, diff --git a/src/SponsorLink/Tests/Sample.cs b/src/SponsorLink/Tests/Sample.cs index 3ea4a328..8ef1ae81 100644 --- a/src/SponsorLink/Tests/Sample.cs +++ b/src/SponsorLink/Tests/Sample.cs @@ -16,15 +16,23 @@ public class Sample(ITestOutputHelper output) [InlineData("es-AR", SponsorStatus.Unknown)] [InlineData("es-AR", SponsorStatus.Expiring)] [InlineData("es-AR", SponsorStatus.Expired)] - [InlineData("es-AR", SponsorStatus.Sponsor)] + [InlineData("es-AR", SponsorStatus.User)] + [InlineData("es-AR", SponsorStatus.Contributor)] + [InlineData("es", SponsorStatus.Unknown)] + [InlineData("es", SponsorStatus.Expiring)] + [InlineData("es", SponsorStatus.Expired)] + [InlineData("es", SponsorStatus.User)] + [InlineData("es", SponsorStatus.Contributor)] [InlineData("en", SponsorStatus.Unknown)] [InlineData("en", SponsorStatus.Expiring)] [InlineData("en", SponsorStatus.Expired)] - [InlineData("en", SponsorStatus.Sponsor)] + [InlineData("en", SponsorStatus.User)] + [InlineData("en", SponsorStatus.Contributor)] [InlineData("", SponsorStatus.Unknown)] [InlineData("", SponsorStatus.Expiring)] [InlineData("", SponsorStatus.Expired)] - [InlineData("", SponsorStatus.Sponsor)] + [InlineData("", SponsorStatus.User)] + [InlineData("", SponsorStatus.Contributor)] public void Test(string culture, SponsorStatus kind) { Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = @@ -61,9 +69,10 @@ public void RenderSponsorables() DiagnosticDescriptor GetDescriptor(string[] sponsorable, string product, string prefix, SponsorStatus status) => status switch { SponsorStatus.Unknown => DiagnosticsManager.CreateUnknown(sponsorable, product, prefix), - SponsorStatus.Sponsor => DiagnosticsManager.CreateSponsor(sponsorable, prefix), SponsorStatus.Expiring => DiagnosticsManager.CreateExpiring(sponsorable, prefix), SponsorStatus.Expired => DiagnosticsManager.CreateExpired(sponsorable, prefix), + SponsorStatus.User => DiagnosticsManager.CreateSponsor(sponsorable, prefix), + SponsorStatus.Contributor => DiagnosticsManager.CreateContributor(sponsorable, prefix), _ => throw new NotImplementedException(), }; } \ No newline at end of file