Make YAML Linter validate server/client-only components (#26809)
* YAML Linter now validates invalid fields in server-only and client-only components * Update to change in engine PR * Use reflection manager to get the lists of client/server assemblies. Also made it use a hashset on type instead of the previous code. * I'm dumb my bad. * Fix 2 errors that snuck through, showing why we need this. --------- Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
This commit is contained in:
@@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Content.IntegrationTests;
|
using Content.IntegrationTests;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
|
using Robust.Shared.Reflection;
|
||||||
using Robust.Shared.Serialization.Markdown.Validation;
|
using Robust.Shared.Serialization.Markdown.Validation;
|
||||||
using Robust.Shared.Timing;
|
using Robust.Shared.Timing;
|
||||||
using Robust.Shared.Utility;
|
using Robust.Shared.Utility;
|
||||||
@@ -103,9 +105,13 @@ namespace Content.YAMLLinter
|
|||||||
return (yamlErrors, fieldErrors);
|
return (yamlErrors, fieldErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(Dictionary<string, HashSet<ErrorNode>> YamlErrors , List<string> FieldErrors)>
|
public static async Task<(Dictionary<string, HashSet<ErrorNode>> YamlErrors, List<string> FieldErrors)>
|
||||||
RunValidation()
|
RunValidation()
|
||||||
{
|
{
|
||||||
|
var (clientAssemblies, serverAssemblies) = await GetClientServerAssemblies();
|
||||||
|
var serverTypes = serverAssemblies.SelectMany(n => n.GetTypes()).Select(t => t.Name).ToHashSet();
|
||||||
|
var clientTypes = clientAssemblies.SelectMany(n => n.GetTypes()).Select(t => t.Name).ToHashSet();
|
||||||
|
|
||||||
var yamlErrors = new Dictionary<string, HashSet<ErrorNode>>();
|
var yamlErrors = new Dictionary<string, HashSet<ErrorNode>>();
|
||||||
|
|
||||||
var serverErrors = await ValidateServer();
|
var serverErrors = await ValidateServer();
|
||||||
@@ -117,9 +123,18 @@ namespace Content.YAMLLinter
|
|||||||
var newErrors = val.Where(n => n.AlwaysRelevant).ToHashSet();
|
var newErrors = val.Where(n => n.AlwaysRelevant).ToHashSet();
|
||||||
|
|
||||||
// We include sometimes-relevant errors if they exist both for the client & server
|
// We include sometimes-relevant errors if they exist both for the client & server
|
||||||
if (clientErrors.Item1.TryGetValue(key, out var clientVal))
|
if (clientErrors.YamlErrors.TryGetValue(key, out var clientVal))
|
||||||
newErrors.UnionWith(val.Intersect(clientVal));
|
newErrors.UnionWith(val.Intersect(clientVal));
|
||||||
|
|
||||||
|
// Include any errors that relate to server-only types
|
||||||
|
foreach (var errorNode in val)
|
||||||
|
{
|
||||||
|
if (errorNode is FieldNotFoundErrorNode fieldNotFoundNode && !clientTypes.Contains(fieldNotFoundNode.FieldType.Name))
|
||||||
|
{
|
||||||
|
newErrors.Add(errorNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (newErrors.Count != 0)
|
if (newErrors.Count != 0)
|
||||||
yamlErrors[key] = newErrors;
|
yamlErrors[key] = newErrors;
|
||||||
}
|
}
|
||||||
@@ -135,6 +150,15 @@ namespace Content.YAMLLinter
|
|||||||
errors.UnionWith(val.Where(n => n.AlwaysRelevant));
|
errors.UnionWith(val.Where(n => n.AlwaysRelevant));
|
||||||
else
|
else
|
||||||
yamlErrors[key] = newErrors;
|
yamlErrors[key] = newErrors;
|
||||||
|
|
||||||
|
// Include any errors that relate to client-only types
|
||||||
|
foreach (var errorNode in val)
|
||||||
|
{
|
||||||
|
if (errorNode is FieldNotFoundErrorNode fieldNotFoundNode && !serverTypes.Contains(fieldNotFoundNode.FieldType.Name))
|
||||||
|
{
|
||||||
|
newErrors.Add(errorNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, combine the prototype ID field errors.
|
// Finally, combine the prototype ID field errors.
|
||||||
@@ -145,5 +169,23 @@ namespace Content.YAMLLinter
|
|||||||
|
|
||||||
return (yamlErrors, fieldErrors);
|
return (yamlErrors, fieldErrors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<(Assembly[] clientAssemblies, Assembly[] serverAssemblies)>
|
||||||
|
GetClientServerAssemblies()
|
||||||
|
{
|
||||||
|
await using var pair = await PoolManager.GetServerClient();
|
||||||
|
|
||||||
|
var result = (GetAssemblies(pair.Client), GetAssemblies(pair.Server));
|
||||||
|
|
||||||
|
await pair.CleanReturnAsync();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
Assembly[] GetAssemblies(RobustIntegrationTest.IntegrationInstance instance)
|
||||||
|
{
|
||||||
|
var refl = instance.ResolveDependency<IReflectionManager>();
|
||||||
|
return refl.Assemblies.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -521,7 +521,6 @@
|
|||||||
nutrientConsumption: 0.70
|
nutrientConsumption: 0.70
|
||||||
idealLight: 8
|
idealLight: 8
|
||||||
idealHeat: 298
|
idealHeat: 298
|
||||||
juicy: true
|
|
||||||
growthStages: 2
|
growthStages: 2
|
||||||
splatPrototype: PuddleSplatter
|
splatPrototype: PuddleSplatter
|
||||||
chemicals:
|
chemicals:
|
||||||
|
|||||||
@@ -481,7 +481,6 @@
|
|||||||
- !type:OrganType
|
- !type:OrganType
|
||||||
type: Animal
|
type: Animal
|
||||||
shouldHave: false
|
shouldHave: false
|
||||||
reagent: Protein
|
|
||||||
type: Local
|
type: Local
|
||||||
visualType: MediumCaution
|
visualType: MediumCaution
|
||||||
messages: [ "generic-reagent-effect-sick" ]
|
messages: [ "generic-reagent-effect-sick" ]
|
||||||
|
|||||||
Reference in New Issue
Block a user