1
1
#include " LintRuleSet.h"
2
2
3
3
#include " AnyObject_LinterDummyClass.h"
4
+ #include " IPluginManager.h"
5
+ #include " JsonObjectWrapper.h"
4
6
#include " LintRunner.h"
5
7
#include " Linter.h"
6
8
#include " AssetRegistry/AssetRegistryModule.h"
7
9
#include " Modules/ModuleManager.h"
8
10
#include " HAL/RunnableThread.h"
9
11
10
- ULintRuleSet::ULintRuleSet (const FObjectInitializer& ObjectInitializer) :
11
- Super(ObjectInitializer) {}
12
+
13
+ TArray<TSharedPtr<FLintRuleViolation>> ULintResults::GetSharedViolations () const {
14
+ TArray<TSharedPtr<FLintRuleViolation>> SharedRuleViolations;
15
+ for (const FLintRuleViolation& Violation : Violations) {
16
+ TSharedPtr<FLintRuleViolation> SharedViolation = MakeShared<FLintRuleViolation>(Violation);
17
+ SharedViolation->PopulateAssetData ();
18
+ SharedRuleViolations.Push (SharedViolation);
19
+ }
20
+
21
+ return SharedRuleViolations;
22
+ }
23
+
24
+ TSharedPtr<FJsonObject> ULintResults::GenerateJsonReport () const {
25
+ auto Report = MakeShared<FJsonObject>();
26
+
27
+ Report->SetStringField (" Project" , FPaths::GetBaseFilename (FPaths::GetProjectFilePath ()));
28
+ Report->SetStringField (" Result" , Result.ToString ());
29
+ Report->SetNumberField (" Warnings" , Warnings);
30
+ Report->SetNumberField (" Errors" , Errors);
31
+
32
+ TArray<TSharedPtr<FJsonValue>> PathArray;
33
+ for (const auto & Path : Paths) {
34
+ PathArray.Add (MakeShared<FJsonValueString>(Path));
35
+ }
36
+ Report->SetArrayField (" Paths" , PathArray);
37
+
38
+ TArray<TSharedPtr<FJsonValue>> AssetsArray;
39
+ for (const auto & Asset : CheckedAssets) {
40
+ #if UE_VERSION_NEWER_THAN(5, 1, 0)
41
+ AssetsArray.Add (MakeShared<FJsonValueString>(Asset.GetObjectPathString ()));
42
+ #else
43
+ AssetsArray.Add (MakeShared<FJsonValueString>(Asset.ObjectPath .ToString ()));
44
+ #endif
45
+ }
46
+ Report->SetArrayField (" CheckedAssets" , AssetsArray);
47
+
48
+ TArray<TSharedPtr<FJsonValue>> ViolationsArray;
49
+ for (const UObject* Violator : FLintRuleViolation::AllRuleViolationViolators (Violations)) {
50
+ TSharedPtr<FJsonObject> ViolationObject = MakeShareable (new FJsonObject);
51
+
52
+ FAssetData AssetData;
53
+ TArray<FLintRuleViolation> ViolatorViolations = FLintRuleViolation::AllRuleViolationsWithViolator (Violations, Violator);
54
+
55
+ if (ViolatorViolations.Num () > 0 ) {
56
+ ViolatorViolations[0 ].PopulateAssetData ();
57
+ AssetData = ViolatorViolations[0 ].ViolatorAssetData ;
58
+
59
+ ViolationObject->SetStringField (" AssetName" , AssetData.AssetName .ToString ());
60
+ ViolationObject->SetStringField (" AssetFullName" , AssetData.GetFullName ());
61
+ #if UE_VERSION_NEWER_THAN(5, 1, 0)
62
+ ViolationObject->SetStringField (" AssetPath" , AssetData.GetObjectPathString ());
63
+ #else
64
+ ViolationObject->SetStringField (" ViolatorAssetPath" , AssetData.ObjectPath .ToString ());
65
+ #endif
66
+ // @TODO: Thumbnail export?
67
+
68
+ TArray<TSharedPtr<FJsonValue>> ViolationObjects;
69
+ for (const FLintRuleViolation& Violation : ViolatorViolations) {
70
+ ULintRule* LintRule = Violation.ViolatedRule ->GetDefaultObject <ULintRule>();
71
+ check (LintRule != nullptr );
72
+
73
+ TSharedPtr<FJsonObject> RuleJsonObject = MakeShareable (new FJsonObject);
74
+ RuleJsonObject->SetStringField (" Group" , LintRule->RuleGroup .ToString ());
75
+ RuleJsonObject->SetStringField (" Title" , LintRule->RuleTitle .ToString ());
76
+ RuleJsonObject->SetStringField (" Description" , LintRule->RuleDescription .ToString ());
77
+ RuleJsonObject->SetStringField (" RuleURL" , LintRule->RuleURL );
78
+ RuleJsonObject->SetNumberField (" Severity" , static_cast <int32>(LintRule->RuleSeverity ));
79
+ RuleJsonObject->SetStringField (" RecommendedAction" , Violation.RecommendedAction .ToString ());
80
+
81
+ ViolationObjects.Add (MakeShared<FJsonValueObject>(RuleJsonObject));
82
+ }
83
+
84
+ ViolationObject->SetArrayField (" Violations" , ViolationObjects);
85
+ }
86
+
87
+ ViolationsArray.Add (MakeShared<FJsonValueObject>(ViolationObject));
88
+ }
89
+ Report->SetArrayField (" Violators" , ViolationsArray);
90
+
91
+ return Report;
92
+ }
93
+
94
+ FString ULintResults::GenerateJsonReportString () const {
95
+ const TSharedPtr<FJsonObject> Report = GenerateJsonReport ();
96
+
97
+ FString ReportString;
98
+ const TSharedRef<TJsonWriter<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>> Writer = TJsonWriterFactory<TCHAR, TPrettyJsonPrintPolicy<TCHAR>>::Create (&ReportString);
99
+ FJsonSerializer::Serialize (Report.ToSharedRef (), Writer);
100
+
101
+ return ReportString;
102
+ }
103
+
104
+ FString ULintResults::GenerateHTML () const {
105
+ const FString ReportString = GenerateJsonReportString ();
106
+
107
+ static const FString TemplatePath = IPluginManager::Get ().FindPlugin (" Linter" )->GetBaseDir () / " Resources" /" LintReportTemplate.html" ;
108
+ UE_LOG (LogLinter, Display, TEXT (" Loading HTML report template from %s" ), *TemplatePath);
109
+
110
+ FString Template;
111
+ if (!FFileHelper::LoadFileToString (Template, *TemplatePath)) {
112
+ UE_LOG (LogLinter, Error, TEXT (" Could not load HTML report template." ));
113
+ }
114
+
115
+ Template.ReplaceInline (TEXT (" {% Report %}" ), *ReportString);
116
+ return Template;
117
+ }
12
118
13
119
ULinterNamingConvention* ULintRuleSet::GetNamingConvention () const {
14
120
return NamingConvention.Get ();
15
121
}
16
122
17
- TArray<FLintRuleViolation> ULintRuleSet::LintPath (TArray<FString> AssetPaths, FScopedSlowTask* ParentScopedSlowTask /* = nullptr*/ ) const {
123
+ ULintResults* ULintRuleSet::LintPath (TArray<FString> AssetPaths, FScopedSlowTask* ParentScopedSlowTask /* = nullptr*/ ) const {
18
124
// ReSharper disable once CppExpressionWithoutSideEffects
19
125
NamingConvention.LoadSynchronous ();
20
126
21
- TArray<FLintRuleViolation> RuleViolations ;
127
+ ULintResults* Results = NewObject<ULintResults>() ;
22
128
23
129
if (AssetPaths.Num () == 0 ) {
24
130
AssetPaths.Push (TEXT (" /Game" ));
25
131
}
132
+ Results->Paths = AssetPaths;
26
133
27
134
// Begin loading assets
28
135
const FAssetRegistryModule& AssetRegistryModule = FModuleManager::LoadModuleChecked<FAssetRegistryModule>(TEXT (" AssetRegistry" ));
@@ -31,8 +138,6 @@ TArray<FLintRuleViolation> ULintRuleSet::LintPath(TArray<FString> AssetPaths, FS
31
138
AssetRegistryModule.Get ().SearchAllAssets (/* bSynchronousSearch =*/ true );
32
139
UE_LOG (LogLinter, Display, TEXT (" Finished loading the asset registry. Loading assets..." ));
33
140
34
- TArray<FAssetData> AssetList;
35
-
36
141
FARFilter ARFilter;
37
142
ARFilter.bRecursivePaths = true ;
38
143
@@ -41,23 +146,23 @@ TArray<FLintRuleViolation> ULintRuleSet::LintPath(TArray<FString> AssetPaths, FS
41
146
ARFilter.PackagePaths .Push (FName (*AssetPath));
42
147
}
43
148
44
- AssetRegistryModule.Get ().GetAssets (ARFilter, AssetList );
149
+ AssetRegistryModule.Get ().GetAssets (ARFilter, Results-> CheckedAssets );
45
150
46
151
TArray<FLintRunner*> LintRunners;
47
152
TArray<FRunnableThread*> Threads;
48
153
49
154
if (ParentScopedSlowTask != nullptr ) {
50
- ParentScopedSlowTask->TotalAmountOfWork = AssetList .Num () + 2 ;
155
+ ParentScopedSlowTask->TotalAmountOfWork = Results-> CheckedAssets .Num () + 2 ;
51
156
ParentScopedSlowTask->CompletedWork = 0 .0f ;
52
157
}
53
158
54
- for (const FAssetData& Asset : AssetList ) {
159
+ for (const FAssetData& Asset : Results-> CheckedAssets ) {
55
160
check (Asset.IsValid ());
56
161
UE_LOG (LogLinter, Verbose, TEXT (" Creating Lint Thread for asset \" %s\" ." ), *Asset.AssetName .ToString ());
57
162
UObject* Object = Asset.GetAsset ();
58
163
check (Object != nullptr );
59
164
60
- FLintRunner* Runner = new FLintRunner (Object, this , &RuleViolations , ParentScopedSlowTask);
165
+ FLintRunner* Runner = new FLintRunner (Object, this , &Results-> Violations , ParentScopedSlowTask);
61
166
check (Runner != nullptr );
62
167
63
168
LintRunners.Add (Runner);
@@ -88,20 +193,24 @@ TArray<FLintRuleViolation> ULintRuleSet::LintPath(TArray<FString> AssetPaths, FS
88
193
ParentScopedSlowTask->EnterProgressFrame (1 .0f , NSLOCTEXT(" Linter" , " ScanTaskFinished" , " Tabulating Data..." ));
89
194
}
90
195
91
- return RuleViolations;
92
- }
93
-
94
- TArray<TSharedPtr<FLintRuleViolation>> ULintRuleSet::LintPathShared (const TArray<FString> AssetPaths, FScopedSlowTask* ParentScopedSlowTask /* = nullptr*/ ) const {
95
- TArray<FLintRuleViolation> RuleViolations = LintPath (AssetPaths, ParentScopedSlowTask);
96
-
97
- TArray<TSharedPtr<FLintRuleViolation>> SharedRuleViolations;
98
- for (const FLintRuleViolation& Violation : RuleViolations) {
99
- TSharedPtr<FLintRuleViolation> SharedViolation = MakeShared<FLintRuleViolation>(Violation);
100
- SharedViolation->PopulateAssetData ();
101
- SharedRuleViolations.Push (SharedViolation);
196
+ // Count Errors and Warnings
197
+ for (const FLintRuleViolation& Violation : Results->Violations ) {
198
+ if (Violation.ViolatedRule ->GetDefaultObject <ULintRule>()->RuleSeverity <= ELintRuleSeverity::Error) {
199
+ Results->Errors ++;
200
+ } else {
201
+ Results->Warnings ++;
202
+ }
102
203
}
103
204
104
- return SharedRuleViolations;
205
+ // Generate Result String
206
+ Results->Result = FText::FormatNamed (
207
+ FText::FromString (" Linted {NumAssets} Assets: {NumWarnings} {NumWarnings}|plural(one=warning,other=warnings), {NumErrors} {NumErrors}|plural(one=error,other=errors)." ),
208
+ TEXT (" NumAssets" ), FText::FromString (FString::FromInt (Results->CheckedAssets .Num ())),
209
+ TEXT (" NumWarnings" ), FText::FromString (FString::FromInt (Results->Warnings )),
210
+ TEXT (" NumErrors" ), FText::FromString (FString::FromInt (Results->Errors ))
211
+ );
212
+
213
+ return Results;
105
214
}
106
215
107
216
const FLintRuleList* ULintRuleSet::GetLintRuleListForClass (const TSoftClassPtr<UObject> Class) const {
0 commit comments