Skip to content

Commit eeb1546

Browse files
committed
Added new properties and tests, updated method checks
Added `DoesAddOperator` property in `AppExtensionsReceiver.cs` and `NeonOperatorGenerateCrdsLive` in `Neon.Operator.Analyzers.targets` and `Neon.Operator.targets`. Updated `AppExtensionsGenerator.cs` to check `DoesAddOperator` instead of `IsTestProject`. `CustomResourceDefinitionGenerator.cs` now checks process name against a new array and `NeonOperatorGenerateCrdsLive` property. Added `Test_AppExtensions.cs` with tests for `UseKubernetesOperator` method invocation.
1 parent 7f6174d commit eeb1546

File tree

6 files changed

+191
-8
lines changed

6 files changed

+191
-8
lines changed

src/Neon.Operator.Analyzers/Generators/AppExtensionsGenerator.cs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,11 @@ public Assembly OnResolveAssembly(object sender, ResolveEventArgs args)
6666

6767
public void Execute(GeneratorExecutionContext context)
6868
{
69-
if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.IsTestProject", out var isTestProject))
69+
var doesAddOperator = ((AppExtensionsReceiver)context.SyntaxReceiver)?.DoesAddOperator;
70+
71+
if (doesAddOperator == false)
7072
{
71-
if (bool.TryParse(isTestProject, out var isTestProjectBool))
72-
{
73-
if (isTestProjectBool == true)
74-
{
75-
return;
76-
}
77-
}
73+
return;
7874
}
7975

8076
var metadataLoadContext = new MetadataLoadContext(context.Compilation);

src/Neon.Operator.Analyzers/Generators/CustomResourceDefinitionGenerator.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
using Neon.Operator.Webhooks;
3939
using Neon.Roslyn;
4040

41+
using Microsoft.CodeAnalysis;
42+
4143
using MetadataLoadContext = Neon.Roslyn.MetadataLoadContext;
4244
using XmlDocumentationProvider = Neon.Roslyn.XmlDocumentationProvider;
4345

@@ -59,6 +61,8 @@ public class CustomResourceDefinitionGenerator : ISourceGenerator
5961

6062
public static XmlDocumentationProvider DocumentationProvider { get; set; } = new XmlDocumentationProvider();
6163

64+
private static readonly string[] allowedProcesses = { "VBCSCompiler", "testhost", "dotnet" };
65+
6266
public void Initialize(GeneratorInitializationContext context)
6367
{
6468
AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly;
@@ -89,6 +93,32 @@ public void Execute(GeneratorExecutionContext context)
8993
{
9094
logs = new Dictionary<string, StringBuilder>();
9195

96+
var processName = System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName;
97+
98+
if (!allowedProcesses.Contains(processName))
99+
{
100+
// this is a hack to disable the analyzer during live editing
101+
102+
if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.NeonOperatorGenerateCrdsLive", out var generateCrdsLive))
103+
{
104+
if (bool.TryParse(generateCrdsLive, out bool generateCrdsLiveBool))
105+
{
106+
if (!generateCrdsLiveBool)
107+
{
108+
return;
109+
}
110+
}
111+
else
112+
{
113+
return;
114+
}
115+
}
116+
else
117+
{
118+
return;
119+
}
120+
}
121+
92122
if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.NeonOperatorGenerateCrds", out var generateCrds))
93123
{
94124
if (bool.TryParse(generateCrds, out bool generateCrdsBool))

src/Neon.Operator.Analyzers/Receivers/AppExtensionsReceiver.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
using System;
1919
using System.Collections.Generic;
20+
using System.Diagnostics;
2021
using System.Linq;
2122

2223
using Microsoft.CodeAnalysis;
@@ -27,13 +28,31 @@ namespace Neon.Operator.Analyzers.Receivers
2728
internal class AppExtensionsReceiver : ISyntaxReceiver
2829
{
2930
public List<ClassDeclarationSyntax> ClassesToRegister { get; } = new List<ClassDeclarationSyntax>();
31+
public bool DoesAddOperator { get; private set; } = false;
32+
3033
private static string[] classAttributes = new string[]
3134
{
3235
"Webhook"
3336
};
3437

3538
public void OnVisitSyntaxNode(SyntaxNode syntaxNode)
3639
{
40+
if (syntaxNode is InvocationExpressionSyntax)
41+
{
42+
try
43+
{
44+
InvocationExpressionSyntax methodSyntax = (InvocationExpressionSyntax)syntaxNode;
45+
if (((MemberAccessExpressionSyntax)methodSyntax.Expression).Name.Identifier.ValueText == "UseKubernetesOperator")
46+
{
47+
DoesAddOperator = true;
48+
}
49+
}
50+
catch
51+
{
52+
// pass
53+
}
54+
}
55+
3756
if (syntaxNode is ClassDeclarationSyntax)
3857
{
3958
var attributeSyntaxes = syntaxNode.DescendantNodes().OfType<AttributeSyntax>();

src/Neon.Operator.Analyzers/build/Neon.Operator.Analyzers.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<CompilerVisibleProperty Include="NeonOperatorOlmOutputDir" />
77
<CompilerVisibleProperty Include="NeonOperatorGenerateRbac" />
88
<CompilerVisibleProperty Include="NeonOperatorGenerateCrds" />
9+
<CompilerVisibleProperty Include="NeonOperatorGenerateCrdsLive" />
910
<CompilerVisibleProperty Include="NeonOperatorWebhookOutputDir" />
1011
<CompilerVisibleProperty Include="NeonOperatorLeaderElectionDisabled" />
1112
<CompilerVisibleProperty Include="NeonOperatorAutoRegisterWebhooks" />

src/Neon.Operator/build/Neon.Operator.targets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<CompilerVisibleProperty Include="NeonOperatorOlmOutputDir" />
77
<CompilerVisibleProperty Include="NeonOperatorGenerateRbac" />
88
<CompilerVisibleProperty Include="NeonOperatorGenerateCrds" />
9+
<CompilerVisibleProperty Include="NeonOperatorGenerateCrdsLive" />
910
<CompilerVisibleProperty Include="NeonOperatorWebhookOutputDir" />
1011
<CompilerVisibleProperty Include="NeonOperatorLeaderElectionDisabled" />
1112
<CompilerVisibleProperty Include="NeonOperatorAutoRegisterWebhooks" />
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
// -----------------------------------------------------------------------------
2+
// FILE: TestAppExtensions.cs
3+
// CONTRIBUTOR: NEONFORGE Team
4+
// COPYRIGHT: Copyright © 2005-2024 by NEONFORGE LLC. All rights reserved.
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License").
7+
// You may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
18+
using System;
19+
using System.Collections.Generic;
20+
using System.ComponentModel.DataAnnotations;
21+
using System.Linq;
22+
using System.Text;
23+
using System.Threading.Tasks;
24+
25+
using FluentAssertions;
26+
27+
using k8s.Models;
28+
using Neon.IO;
29+
using Neon.Operator.Analyzers;
30+
31+
using Neon.Operator.Attributes;
32+
33+
using Neon.Roslyn.Xunit;
34+
35+
namespace Test.Analyzers
36+
{
37+
public class Test_AppExtensions
38+
{
39+
[Fact]
40+
public async Task TestUseKubernetesOperator()
41+
{
42+
var source = @"
43+
using Microsoft.AspNetCore.Builder;
44+
using Microsoft.Extensions.Configuration;
45+
using Microsoft.Extensions.DependencyInjection;
46+
using Microsoft.Extensions.Logging;
47+
48+
using Neon.Operator;
49+
50+
namespace TestNamespace
51+
{
52+
public class Startup
53+
{
54+
public IConfiguration Configuration { get; }
55+
56+
public Startup(IConfiguration configuration)
57+
{
58+
this.Configuration = configuration;
59+
}
60+
61+
public void ConfigureServices(IServiceCollection services)
62+
{
63+
services.AddLogging(configure =>
64+
{
65+
configure.ClearProviders();
66+
configure.AddConsole();
67+
});
68+
69+
services.AddKubernetesOperator();
70+
}
71+
72+
public void Configure(IApplicationBuilder app)
73+
{
74+
app.UseKubernetesOperator();
75+
}
76+
}
77+
}";
78+
var testCompilation = new TestCompilationBuilder()
79+
.AddSourceGenerator<AppExtensionsGenerator>()
80+
.AddSource(source)
81+
.AddAssembly(typeof(KubernetesEntityAttribute).Assembly)
82+
.AddAssembly(typeof(AdditionalPrinterColumnAttribute).Assembly)
83+
.Build();
84+
85+
testCompilation.Sources.Should().HaveCount(1);
86+
}
87+
88+
[Fact]
89+
public async Task TestDontUseKubernetesOperator()
90+
{
91+
var source = @"
92+
using Microsoft.AspNetCore.Builder;
93+
using Microsoft.Extensions.Configuration;
94+
using Microsoft.Extensions.DependencyInjection;
95+
using Microsoft.Extensions.Logging;
96+
97+
using Neon.Operator;
98+
99+
namespace TestNamespace
100+
{
101+
public class Startup
102+
{
103+
public IConfiguration Configuration { get; }
104+
105+
public Startup(IConfiguration configuration)
106+
{
107+
this.Configuration = configuration;
108+
}
109+
110+
public void ConfigureServices(IServiceCollection services)
111+
{
112+
services.AddLogging(configure =>
113+
{
114+
configure.ClearProviders();
115+
configure.AddConsole();
116+
});
117+
118+
services.AddKubernetesOperator();
119+
}
120+
121+
public void Configure(IApplicationBuilder app)
122+
{
123+
}
124+
}
125+
}";
126+
var testCompilation = new TestCompilationBuilder()
127+
.AddSourceGenerator<AppExtensionsGenerator>()
128+
.AddSource(source)
129+
.AddAssembly(typeof(KubernetesEntityAttribute).Assembly)
130+
.AddAssembly(typeof(AdditionalPrinterColumnAttribute).Assembly)
131+
.Build();
132+
133+
testCompilation.Sources.Should().BeEmpty();
134+
}
135+
}
136+
}

0 commit comments

Comments
 (0)