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

WIP: add UseCompatibleTypes Rule, including related resources. Refactor UseCompatibleCmdlets Rule. #960

Closed
wants to merge 11 commits into from

Conversation

MiaRomero
Copy link
Member

PR Summary

Add UseCompatibleTypes rule which checks for compatibility with a specified version of PowerShell on a specified platform. Refactor UseCompatibleCmdlets to be similar since both use the same resources.
Need:
updated type/cmdlet dictionaries for Core 6.0.2
rule documentation

PR Checklist

Note: Tick the boxes below that apply to this pull request by putting an x between the square brackets. Please mark anything not applicable to this PR NA.

  • PR has a meaningful title
    • Use the present tense and imperative mood when describing your changes
  • Summarized changes
  • User facing documentation needed
  • Change is not breaking
  • Make sure you've added a new test if existing tests do not effectively test the code changed
  • This PR is ready to merge and is not work in progress
    • If the PR is work in progress, please add the prefix WIP: to the beginning of the title and remove the prefix when the PR is ready

@bergmeister
Copy link
Collaborator

bergmeister commented Apr 3, 2018

Thanks for your work and welcome to PSSA! Some quick things that I found when scanning the changes: The command data files are of version 6.0.1 and not 6.0.2. The osx file should use the word macos instead of osx, see recently merged PR #947 for why. Also have a look at my current PR #954 (I'm OK to close or modify mine instead)

@MiaRomero MiaRomero force-pushed the CompatibleTypes branch 2 times, most recently from e3c35d9 to 4eb3ae4 Compare May 15, 2018 20:33
@bergmeister
Copy link
Collaborator

@MiaRomero Please update your branch and resolve merge conflicts

@bergmeister bergmeister added this to the 1.18 milestone May 22, 2018
@JamesWTruher JamesWTruher requested a review from rjmholt August 21, 2018 17:31
@JamesWTruher JamesWTruher self-assigned this Aug 21, 2018
Copy link
Contributor

@rjmholt rjmholt left a comment

Choose a reason for hiding this comment

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

Did a preliminary review pass -- generally looks good, but I've left some comments

/// </summary>
public string GetSourceName()
// Name of known issues list file.
private readonly string knownIssuesFileName = "knownCmdletIssues.json";
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd move all the readonly private vars to the top in their own group

if (!IsInitialized)
{
Initialize();
}

if (hasInitializationError)
{
yield break;
Console.WriteLine("There was an error running the UseCompatibleCmdlets Rule. Please check the error log in the Settings file for more info.");
return new DiagnosticRecord[0];
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be a static variable ideally to prevent new allocations on failure.

{
return AstVisitAction.SkipChildren;
return new DiagnosticRecord[0];
Copy link
Contributor

Choose a reason for hiding this comment

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

Same thing about the static variable

var commandName = commandAst.GetCommandName();
if (commandName == null)
// If we have no cmdlets to check, we can exit from this rule.
if (commandAsts.Count() == 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd move this check up to be right under the commandAsts so it fails early

yield return dr;
}
}
customCommands = new List<string>();
Copy link
Contributor

Choose a reason for hiding this comment

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

We seem to do diagnosticRecords.Clear() but also customCommands = new List<string>().

I don't exactly agree with the prevailing style of this class, but in its spirit maybe we need to:

  • Make all the collection fields readonly
  • Have a Clear() method that clears all the collections that should be empty when a rule runs

The ideal way I would do this would be to:

  • Get rid of the Initialize() method
  • Put initialisation into the constructor or as lazy fields

But that might be too far.

But we should try and be consistent about:

  • Having collections as private fields vs local variables
  • Using Clear() vs reassigning an empty collection
  • Having readonly fields where it makes sense

I say all this because I think dealing with customCommands should be moved down to the loop that adds elements to it, but if we move the early exit up then we might have a dirty collection

string settingsPath = Settings.GetShippedSettingsDirectory();

if (String.IsNullOrEmpty(settingsPath))
{
Copy link
Contributor

Choose a reason for hiding this comment

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

If this happens, the failure will be silent?

{
string name = type.Name.ToString();
string nameSpace = type.Namespace.ToString();
string fullName = nameSpace + "." + name;
Copy link
Contributor

Choose a reason for hiding this comment

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

The namespace of the type might be empty, in which case the . will not be correct. Also, if the type is nested, the full type name will be different

dynamic typeList = deserializedObject.Types;
foreach (dynamic type in typeList)
{
string name = type.Name.ToString();
Copy link
Contributor

Choose a reason for hiding this comment

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

These should already be strings -- it might be a case of casting them rather than calling ToString()? Unless there's something occuring in deserialisation?

List<fullTypeNameObject> fullNameObjectList = new List<fullTypeNameObject>();

// Check to see if our object is a CommandAst.
if (typeObject is CommandAst)
Copy link
Contributor

Choose a reason for hiding this comment

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

A large nested if statement like this should be refactorable with returns hopefully

{
string name;
ScriptBlock script;
// Create a TypeExpressionAst from the CommandElementAst
Copy link
Contributor

Choose a reason for hiding this comment

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

There might be a better way to do this -- I'll look into it

@bergmeister
Copy link
Collaborator

@rjmholt All the added/removed/renamed JSON files should probably be reverted as this PR was created before I added the proper ones for 6.0.2. The ones for 6.1 should only be added once 6.1 goes GA

@bergmeister bergmeister removed this from the 1.18 milestone Mar 5, 2019
@JamesWTruher
Copy link
Contributor

I'm closing this now as #1133 was taken

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.

5 participants