Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add beginnings of PSScriptAnalyzer 2.0 #1476

Merged
merged 2 commits into from
Jun 4, 2020
Merged

Conversation

rjmholt
Copy link
Contributor

@rjmholt rjmholt commented May 6, 2020

Start of the PSScriptAnalyzer 2.0 project.

I'll open up issues to describe the outstanding work items I have in my mind and label/milestone them appropriately.

@rjmholt rjmholt added this to the 2.0 milestone May 6, 2020
Copy link
Collaborator

@bergmeister bergmeister left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here are some comments, looks ok overall, I don't have time for a full line by line review, which I suggest you get from someone in your team since PSSA 2 is a big undertaking.

{
foreach (string rulePath in configuration.RulePaths)
{
string extension = Path.GetExtension(rulePath).ToLower();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following the learnings from #1099, we should be using ToLowerInvariant. But looking at the usage in the switch statement below, we should rather be using C# pattern matching for a case insensitive comparison inside a switch statement, see here for an example: https://stackoverflow.com/a/44447980

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a huge fan of the reverse switch. Will replace with if


public ScriptAnalyzer Build()
{
IRuleProvider ruleProvider = _ruleProviders.Count == 1
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me it feels like the special case of 1 rule should be handled inside CompositeRuleProvider from a consumer's perspective.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it's done here for efficiency. We can decide what's best when we're further along


namespace Microsoft.PowerShell.ScriptAnalyzer.Builder
{
public class ScriptAnalyzerBuilder
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please try to keep the number of publicly exposed classes/methods generally minimal and instead use internal?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very much agree. My intent is to try and keep things behind interfaces where it makes sense to. In this case, I'm intending for the builder to be public for hosts, but certainly we will review the API surface


public static IReadOnlyDictionary<string, IRuleConfiguration> RuleConfiguration { get; } = new Dictionary<string, IRuleConfiguration>(StringComparer.OrdinalIgnoreCase)
{
{ "PS/AvoidUsingEmptyCatchBlock", null },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we eliminate the hard-coding here and use something like an attribute on the rule whether to run the rule by default or rely on something like typeof/nameof ? The PS prefix should also be defined only once.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think some of this will change. The key part though is that I want to improve cold start performance by eliminating reflection and should also have a nice declarative way to list rules.


private static IPowerShellCommandDatabase InstantiatePowerShellCommandDatabase()
{
using (Runspace runspace = RunspaceFactory.CreateRunspace())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about specifying the runspace pool as something like number of rules plus 2 (or whatever makes sense)? Just an idea. At the moment we do hard-code the default.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This particular concept I think I will rework and we can figure out the runspace configuration after that


namespace Microsoft.PowerShell.ScriptAnalyzer.Configuration.Json
{
internal class JsonConfigurationConverter : JsonConverter<JsonScriptAnalyzerConfiguration>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't looked into details but can we please support JSONC (json with comments)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm hoping we can -- I'll see about writing some tests down the line


case VariableExpressionAst varExprAst:
// $true and $false are VariableExpressionAsts, so look for them here
switch (varExprAst.VariablePath.UserPath.ToLowerInvariant())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boolean.TryParse?

}

/*
internal class DataflowRuleExecutor : IRuleExecutor
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WIP?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this didn't work initially but I'm hoping to keep it to work on to see if we can improve it. Alternatively, it might be easier to convert this to a Channel now

Copyright = '(c) Microsoft Corporation'

# Description of the functionality provided by this module
Description = 'PSScriptAnalyzer provides script analysis and checks for potential code defects in the scripts by applying a group of built-in or customized rules on the scripts being analyzed.'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add that it is a formatter as well


CompatiblePSEditions = @('Core', 'Desktop')

# HelpInfo URI of this module
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should use the opportunity to remove some of those commented out things in the psd1 but HelpInfoUri could actually be useful to set

@rjmholt
Copy link
Contributor Author

rjmholt commented Jun 4, 2020

Merging this to the WIP fork for PSSA2. Will continue working on that branch

@rjmholt rjmholt merged commit 20f3acf into PowerShell:pssa2 Jun 4, 2020
@rjmholt rjmholt deleted the rob-pssa2 branch June 4, 2020 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants