Skip to content

Commit

Permalink
Added DisableLogs attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
helto4real committed Apr 26, 2020
1 parent 5596397 commit 4c6a6ed
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 3 deletions.
42 changes: 41 additions & 1 deletion src/App/NetDaemon.App/Common/Attributes.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Collections.Generic;

namespace JoySoftware.HomeAssistant.NetDaemon.Common
{
/// <summary>
Expand All @@ -15,7 +17,7 @@ public sealed class HomeAssistantStateChangedAttribute : System.Attribute
// See the attribute guidelines at
// http://go.microsoft.com/fwlink/?LinkId=85236
private string _entityId;


private readonly object? _to;
private readonly object? _from;
private readonly bool _allChanges;
Expand Down Expand Up @@ -55,4 +57,42 @@ public HomeAssistantStateChangedAttribute(string entityId, object? to = null, ob
/// </summary>
public object? To => _to;
}

/// <summary>
/// Type of log to supress
/// </summary>
public enum SupressLogType
{
/// <summary>
/// Supress Missing Execute Error in a method
/// </summary>
MissingExecute
}


/// <summary>
/// Attribute to mark function as callback for state changes
/// </summary>
[System.AttributeUsage(System.AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
public sealed class DisableLogAttribute : System.Attribute
{
// See the attribute guidelines at
// http://go.microsoft.com/fwlink/?LinkId=85236
private SupressLogType[] _logTypesToSupress;


/// <summary>
/// Default constructor
/// </summary>
/// <param name="logTypes">List of logtypes to supress</param>
public DisableLogAttribute(params SupressLogType[] logTypes)
{
_logTypesToSupress = logTypes;
}

/// <summary>
/// Log types to supress
/// </summary>
public IEnumerable<SupressLogType> LogTypesToSupress => _logTypesToSupress;
}
}
24 changes: 22 additions & 2 deletions src/DaemonRunner/DaemonRunner/Service/App/CodeManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -593,12 +593,21 @@ private void WarnIfExecuteIsMissing(SyntaxTree syntaxTree, CSharpCompilation com

if (symbol is object && symbol.ContainingType.Name == "NetDaemonApp")
{
var disableLogging = false;

var symbolName = symbol.Name;

SyntaxNode? parentInvocationExpression = invocationExpression.Parent;

while (parentInvocationExpression is object)
{
if (parentInvocationExpression is MethodDeclarationSyntax)
{
if (ExpressionContainsDisableLogging((MethodDeclarationSyntax)parentInvocationExpression))
{
disableLogging = true;
}
}
if (parentInvocationExpression is InvocationExpressionSyntax)
{
var parentSymbol = (IMethodSymbol?)semModel?.GetSymbolInfo(invocationExpression).Symbol;
Expand All @@ -611,7 +620,7 @@ private void WarnIfExecuteIsMissing(SyntaxTree syntaxTree, CSharpCompilation com

// Now when we have the top InvocationExpression,
// lets check for Execute and ExecuteAsync
if (ExpressionContainsExecuteInvocations(topInvocationExpression) == false)
if (ExpressionContainsExecuteInvocations(topInvocationExpression) == false && disableLogging == false)
{
var x = syntaxTree.GetLineSpan(topInvocationExpression.Span);
if (linesReported.Contains(x.StartLinePosition.Line) == false)
Expand All @@ -624,7 +633,18 @@ private void WarnIfExecuteIsMissing(SyntaxTree syntaxTree, CSharpCompilation com
}
}

// Todo: Refactor using something smarter than string match. In future use Roslyn
// Todo: Refactor using something smarter than string match. In the future use Roslyn
private bool ExpressionContainsDisableLogging(MethodDeclarationSyntax methodInvocationExpression)
{
var invocationString = methodInvocationExpression.ToFullString();
if (invocationString.Contains("[DisableLog") && invocationString.Contains("SupressLogType.MissingExecute"))
{
return true;
}
return false;
}

// Todo: Refactor using something smarter than string match. In the future use Roslyn
private bool ExpressionContainsExecuteInvocations(InvocationExpressionSyntax invocation)
{
var invocationString = invocation.ToFullString();
Expand Down
16 changes: 16 additions & 0 deletions tests/NetDaemon.Daemon.Tests/DaemonRunner/App/DaemonAppTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,22 @@ public void InsanceAppsThatHasMissingExecuteShouldLogError()

}

[Fact]
public void InsanceAppsThatHasMissingExecuteAndSupressLogsShouldNotLogError()
{
// ARRANGE
var path = Path.Combine(FaultyAppPath, "SupressLogs");
var moqDaemon = new Mock<INetDaemonHost>();
var moqLogger = new LoggerMock();

// ACT
var codeManager = new CodeManager(path, moqLogger.Logger);

// ASSERT
moqLogger.AssertLogged(LogLevel.Error, Times.Exactly(1));

}

public static CodeManager CM(string path) => new CodeManager(path, new LoggerMock().Logger);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using JoySoftware.HomeAssistant.NetDaemon.Common;

/// <summary>
/// Greets (or insults) people when coming home :)
/// </summary>
public class SupressLogs : NetDaemonApp
{
[DisableLog(SupressLogType.MissingExecute)]
public override async Task InitializeAsync()
{
// All warnings in this is supressed
Entity("Test");
await DoStuff();
}

public async Task DoStuff()
{
// This is not supressed
Entity("Test");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

missing_executes:
class: SupressLogs

0 comments on commit 4c6a6ed

Please sign in to comment.