How can a SonarPlugin query its settings? - sonarqube

I'm currently developing a SonarQube plugin and want to ask whether there is a way to query the settings from the sonar-project-properties file at run time.
More specifically, in the sonar-project-properties file you can set the analysis mode to analysis, preview or incremental, e.g., sonar.analysis.mode=analysis.
Due to the problem that preview and incremental mode run into an error, I want to disable the plugin when one of these two modes is specified.
I know that there is the sonar.preview.excludePlugins setting for excluding plugins, however, I cannot use it. In other words, I have to figure out at run-time which mode is set.
Can someone give me a hint, because I haven't found an approach for querying the settings from a sonar-project.properties file?

Plugins can not auto-disable themselves through the standard plugin exclusion properties.
The solution is that your plugin extensions, for instance sensors, read the properties through the component org.sonar.api.config.Settings and then accordingly continue or stop execution. Basically:
public class MySensor implements Sensor {
private final Settings settings;
public MySensor(Settings settings) {
this.settings = settings;
}
public void analyse(Project module, SensorContext context) {
if ("analysis ".equals(settings.getString("sonar.analysis.mode"))) {
return;
}
// else continue...
}
}

Related

Unbound breakpoints when debugging in Blazor Webassembly when using certain attributes/classes

I'm developing a modular blazor application (5.0.2) using VS 2019 (16.8.4), which is structured as follows:
a "Main" Solution, which consists of
RCL
Wasm project to startup the application
several "Sub" solutions which reference the Main RCL (Base components, etc) which consist of
.net5 libraries (Models, Web-service access, etc)
RCL with components, referencing the .net5 libraries (via project reference)
All projects have a post-build event to copy the DLL and PDB files to a certain path, e.g. D:\TMP.
The SubSolution references the MainRCL library via this path.
The Main Wasm project references the SubRCL library also via this path (for adding services at startup/Program.cs).
The MainRCL does not have a reference to SubRCL (components are rendered via reflection/BuildRenderTree() according to configurable UI definition).
Debugging the Main Solution worked perfectly (IIS Express/Application Debugging).
Then I tried to debug the SubModules -> I started debugging from the MainSolution and opened files from the SubModules projects in this VS instance.
At some libraries, debugging was working, but not for the SubRCL ("Unbound Breakpoint"). Then I was able to reproduce the (very strange) issue with sample solutions:
The "MainRCL" provides 2 Attributes:
[AttributeUsage(AttributeTargets.Class)]
public sealed class TestNoEnumAttribute : Attribute
{
public string Name { get; set; }
public string Mode { get; set; }
public TestNoEnumAttribute(string name, string mode)
{
Name = name;
Mode = mode;
}
}
[AttributeUsage(AttributeTargets.Class)]
public sealed class TestEnumAttribute : Attribute
{
public string Name { get; set; }
public EventExecutionMode Mode { get; set; }
public TestEnumAttribute(string name, EventExecutionMode mode)
{
Name = name;
Mode = mode;
}
}
public enum EventExecutionMode
{
AutomaticAll = 0,
ManualConfiguration = 2
}
The SubRCL uses these attributes at a test-method:
[TestNoEnum("Test", "EventExecutionMode.ManualConfiguration")]
//[TestEnum("Test", EventExecutionMode.ManualConfiguration)]
public class Module1Test
{
public int IncreaseNum(int num)
{
var x = new Part1();
var part1Num = x.DoStuff(num);
var newNum = part1Num + 1;
return newNum;
}
}
The class "Part1()" which is called, is located at another library of the SubSolution
The breakpoint at the "DoStuff()" method in Part1 class is always hit (in separate .net5 library).
The breakpoint at the "IncreaseNum()" method is only called when the [TestEnum] attribute is NOT used.
As soon as the [TestEnum] attribute is used, there is an "Unbound Breapoint"; the breakpoint in "DoStuff()" method in another library is still hit.
Then I tried to "add existing project" to SubSolution and added the MainWasm project and started debugging directly from SubSolution -> same behavior.
Is there anything I oversee (e.g. regarding DLL-references or PDB file copy)?
This is already my second approach of trying to debug these modular-structured solutions - first I tried to debug via IIS (How to debug Blazor Webassembly on IIS with VS by attaching to Chrome?), but this was also not successful.
Found out there is an issue with debugging when using attribues with enum parameters:
https://github.com/dotnet/aspnetcore/issues/25380
-> I replaced the enum parameters and debugging is working fine now - Didn't get any feedback when this will be fixed so far
I had the same issue with my Blazor WASM not able to be debugged in VS due to 'Unbound breakpoint'. I have multiple projects running under the same solution and while initially the debugging worked for the WASM, it stopped after a while.
Eventually I was able to find a work around by waiting until all projects loaded and then I could disable the 'Unbound' breakpoint and re-select it. It then worked as expected.
It's not an ideal solution (especially if you have multiple breakpoints while troubleshooting) but it is workable.
I had this problem in .NET 6 and Visual Studio 2022.
I made a codebehind-file component.razor.cs but I also had code in the razor-file itself. Moving the code to the codebehind-file solved the issue and enabled the breakpoints.

Visual Studio 2017 Live Testing exclusions

I'm looking at Live Testing feature in the new Visual Studio (I'm using NUnit).
There is an "exclude" option for unit tests, to indicate that specific tests should not be run (maybe they are integration tests, or slow tests, or whatever).
Where does this information get stored? I don't see any indication in the csproj or anywhere else that a test should not be included in Live Testing. Shouldn't there be some information file somewhere that I can check into source control so the rest of my team doesn't have to manually specify which tests should not be run by live testing?
Include/exclude is a user level feature. This is extremely useful when you want to run a specific set of tests for a particular edit session or to persist your own personal preferences. To prevent tests from running and to persist that information, you could do something like the following:
[ExcludeFromCodeCoverage]
public class SkipLiveFactAttribute : FactAttribute
{
private static bool s_lutRuntimeLoaded = AppDomain.CurrentDomain.GetAssemblies().Any(a => a.GetName().Name == "Microsoft.CodeAnalysis.LiveUnitTesting.Runtime");
public override string Skip => s_lutRuntimeLoaded ? "Test excluded from Live Unit Testing" : "";
}
public class Class1
{
[SkipLiveFact]
public void F()
{
Assert.True(true);
}
}
You can now use the following attributes to specify in source code that you want to exclude targeted test methods from Live Unit Testing:
For xUnit: [Trait("Category", "SkipWhenLiveUnitTesting")]
For NUnit: [Category("SkipWhenLiveUnitTesting")]
For MSTest: [TestCategory("SkipWhenLiveUnitTesting")]
Offical Docs here

Xamarin.forms how to auto save user name like browser

I am developing a mobile application using Xamarin.Forms
I had the following Home page contains login info:
How can we have the application to automatically save the user name, so that they do not have to type it in each time (as in a browser)?
You can use Properties dictionary in Xamarin.Forms Application class. And let the Xamarin.Forms framework handle persisting user name between app restarts and pausing/resuming your app.
Save user name by writing it to Properties dictionary
var properties = Xamarin.Forms.App.Current.Properties;
if(!properties.ContainsKey("username")
{
properties.Add("username", username);
}
else
{
properties["username"] = username;
}
Then, when your login screen is about to appear (for example in OnAppearing method) check Properties for user name:
var properties = Xamarin.Forms.App.Current.Properties;
if(properties.ContainsKey("username")
{
var savedUsername = (string)properties["username"];
}
If it's not there, then it means that this is first time when user log in into your application.
A very similar question was posed just a few days ago - my answer on that question also applies to your question: The best way to save Configuration data in Xamarin.Forms based app?
Essentially, you want to store the information using the native settings functionality. I would advise against using Application.Properties for now. It is currently not reliable on Android, and in the past has had other problems. The nuget package referenced in my linked answer is a better approach and will save you some headache in the future.
The right way to be done is through the App settings plugin
https://github.com/jamesmontemagno/Xamarin.Plugins/tree/master/Settings
What i did in my application is.
1) Installed Plugin.Settings from nuget
2)Added to Helpers->Settings.cs (autogenerated file by plugin) the following
public static class Settings
{
private static ISettings AppSettings
{
get { return CrossSettings.Current; }
}
private const string UserNameKey = "username_key";
private static readonly string UserNameDefault = "demo";
public static string UserName
{
get { return AppSettings.GetValueOrDefault<string>(UserNameKey, UserNameDefault); }
set { AppSettings.AddOrUpdateValue<string>(UserNameKey, value); }
}
}
3)In order to keep the username in the Application Context set
Settings.UserName = ViewModel.Username;
4)When you login screen starts
string username = Settings.UserName;
The answer is simple: persistance. Servers do this by setting cookies containing the data (or reference to it) that they want you to see when rendering the form field.
In order to do this in an app (with Xamarin for instance), you need to store the user's data into a file or database somewhere. Since you're using Xamarin you can probably use some sort of ConfigurationManager to keep track of this.
Obviously you could just create a config file in the local storage you have for your app (I don't think you need permissions to create files in that space).
When you have the info stored somewhere, just retrieve it and set the input's value to it.

How to debug a plugin in on-line version?

I've created a plugin and registered it using hte registration tool. I've also added a step that is supposed to handle a message of creation of an instance. Sadly, the intended behavior doesn't occur.
My guess is that something inside the plugin crashes but I have no idea on how to debug it. Setting up breakpoints is not going to work agains on-line version, I understand, so I'm not even trying.
For legal and technical reasons, I won't be able to lift over the solution to an on-premise installation, neither. Is guessing my only option?
For server-side (plugins) I'm using ITracingService. For client-side I log everything to console. The downside with the first is that you actually need to crash the execution to get to see anything. The downside with the latter is that plugins sometimes get executed without GUI being invoked at all.
When it comes to heavier projects, I simply set up a WCF web service that I call from the plugin and write to that. That way, on one screen, I'm executing the plugin while on the other, I'm getting a nice log file (or just put the sent information to on the screen).
You could, for instance, start with a very basic update of a field on the instance of your entity that's being created. When you have that working, you can always fall back to the last working version. If you don't even get that to work, it mean, probably, that you're setting up the plugin registration incorrectly.
A very efficient way would be to lift over the solution to an on-premise version where you have full control but I see in your question that it's not en option.
In case you could lift the solution to an on-premise version, here's a link on how to debug plugins.
Don't forget that you also have access to the ITracingService.
You can get a reference to it in your Execute method and then write to it every so often in your code to log variables or courses of action that you are attempting or have succeeded with. You can also use it to surface more valuable information when an exception occurs.
It's basically like writing to a console. Then, if anything causes the plug-in to crash at runtime then you can see everything that you've traced when you click Download Log File on the error shown to the user.
Beware though - unless your plug-in actually throws an exception (deliberate or otherwise) then you have no access to whatever was traced.
Example:
public void Execute(IServiceProvider serviceProvider)
{
// Obtain the execution context from the service provider.
IPluginExecutionContext context =
(IPluginExecutionContext)serviceProvider.GetService(
typeof(IPluginExecutionContext));
// Get a reference to the tracing service.
ITracingService tracingService =
(ITracingService)serviceProvider.GetService(typeof(ITracingService));
try
{
tracingService.Trace("Getting entity from InputParameters...");
// may fail for some messages, since "Target" is not present
var myEntity = (Entity)context.InputParameters["Target"];
tracingService.Trace("Got entity OK");
// some other logic here...
}
catch (FaultException<OrganizationServiceFault> ex)
{
_trace.Trace(ex.ToString());
while (ex.InnerException != null)
{
ex = (FaultException<OrganizationServiceFault>)ex.InnerException;
_trace.Trace(ex.ToString());
}
throw new InvalidPluginExecutionException(
string.Format("An error occurred in your plugin: {0}", ex));
}
catch (Exception ex)
{
_trace.Trace(ex.ToString());
while (ex.InnerException != null)
{
ex = ex.InnerException;
_trace.Trace(ex.ToString());
}
throw;
}
}

Why is DbgView missing some trace writes, but the traces can be seen in test runners

Can anyone explain why DbgView misses some of my trace writes ?
I'm using the Enterprise Library 5.0 logging block with a trace listener deriving from the EntLib CustomTraceListener, as below ...
[ConfigurationElementType(typeof(CustomTraceListenerData))]
public class DebugTraceListener : CustomTraceListener
{
public override void Write(string message)
{
Debug.Write(message);
}
public override void WriteLine(string message)
{
Debug.WriteLine(message);
}
public override void TraceData(TraceEventCache eventCache, string source,
TraceEventType eventType, int id, object data)
{
if (data is LogEntry && Formatter != null)
{
WriteLine(Formatter.Format(data as LogEntry));
}
else
{
WriteLine(data.ToString());
}
}
}
I can see all the trace in both the Resharper test runner in VS2010, and in the NUnit GUI tester.
I can also send the trace to a flat file listener and this captures all the trace writes,
BUT when I use DbgView (and also TraceSpy) only some of the trace is being shown.
The other wrinkle is I'm using PostSharp to add the logging as an aspect, via attribute, rather than directly in the business code
I've seen this happen when you have another application running that is also capturing some part of the debug traffic. If you're running an application and have VS2010 debugging some component you won't see whatever debug output is being routed to the IDE instead of DebugView. This can be handy if you're testing client-server applications on the same box at the same time but can cause the issue you describe. Short of that I'd just make sure that Capture Global Win32 is checked from the Capture menu as well (I've seen that make a difference even when I wouldn't have expected it to).
Are the missing messages always the same ones?

Resources