Skip to content

Add Fix switch parameter for 'File' parameter set to auto-correct warnings (#802) #817

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

Merged
merged 32 commits into from
Nov 30, 2017

Conversation

bergmeister
Copy link
Collaborator

Implements #802 (auto-correct warnings) by adding an AutoFix switch parameter for 'File' parameter set, which uses the SuggestedCorrectionExtent information as a correction.

It uses UTF8 to overwrite the existing file with the fix to avoid problems with special characters such as the copyright symbol in psd1 files but this could be enhanced to preserve the encoding of the original file in the future.
This is a a minimum (and hopefully) viable implementation of issue #802. It works when being run against e.g. the whole PowerShell repo here but throws an 'EditableTextInvalidLineEnding' error at some point for one file (this seems to be rather an issue with existing code that fixes EditableText)

… SuggestedCorrectionExtent information as a correction.

It uses UTF8 to read/write the file for avoiding problems with special characters such as the copyright symbol in psd1 files but this probably needs to be enhanced to preserver the encoding of the original file.
This is a a minimum (and hopefully) viable implementation of issue 802. It works for most files of the PowerShell repo but throws a 'EditableTextInvalidLineEnding' error for one file (this seems to be an issue with existing code that fixes EditableText)
@bergmeister
Copy link
Collaborator Author

@kapilmb Only 3 tests that were asserting against the help of the new switch parameter failed, could you give me a pointer please where I could fix them as it did not seem to be obvious to me.

@kapilmb
Copy link

kapilmb commented Sep 8, 2017

Thanks for PR.

To resolve the test failure you will need to add the parameter related help to docs/markdown/Invoke-ScriptAnalyzer.md.

I remember you suggesting adding ShouldProcess. I think we should add it before this makes it to the development branch.

/// Resolves rule violations automatically where possible.
/// </summary>
[Parameter(Mandatory = false, ParameterSetName = "File")]
public SwitchParameter AutoFix
Copy link

Choose a reason for hiding this comment

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

Fix vs AutoFix ? I think Fix. It conveys the some information and is shorter.

Copy link
Collaborator Author

@bergmeister bergmeister Sep 8, 2017

Choose a reason for hiding this comment

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

Ok. I Agree with Fix

{
var scriptFileContentWithAutoFixes = Fix(File.ReadAllText(scriptFilePath));
// Use UTF8 when writing to avoid issues with special characters such as e.g. the copyright symbol in *.psd1 files. This could be improved to detect the encoding in order to preserve it.
File.WriteAllText(scriptFilePath, scriptFileContentWithAutoFixes, Encoding.UTF8);
Copy link

Choose a reason for hiding this comment

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

When we modify a file, we should preserve the file encoding and line endings

Copy link
Collaborator Author

@bergmeister bergmeister Sep 8, 2017

Choose a reason for hiding this comment

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

Agreed. A quick search showed however that detecting the encoding is non-trivial and difficult to get 100% correct. Should we do something like this?

Copy link

Choose a reason for hiding this comment

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

The StreamReader object provides encoding of a file. I think we should that instead of rewriting the logic to detect the encoding.

@@ -1475,6 +1477,13 @@ public IEnumerable<DiagnosticRecord> AnalyzePath(string path, bool searchRecursi
this.BuildScriptPathList(path, searchRecursively, scriptFilePaths);
foreach (string scriptFilePath in scriptFilePaths)
{
if (autoFix)
{
Copy link

@kapilmb kapilmb Sep 8, 2017

Choose a reason for hiding this comment

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

I think the right place for this block is in the InvokeScriptAnalyzerCommand.cs file. We do not need to change behavior 'Analyzepath` method, which should only analyze and not fix.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This would require some re-factoring of the project because one needs to call the private method BuildScriptPathList of the ScriptAnalyzer class first to get the list of files, therefore it would probably be best to extract the BuildScriptPathList method into a separate class. Can you confirm that you really want this or suggest other options?

… in the case of UTF8, a BOM will get added. Update help markdown to fix help related tests.
@bergmeister
Copy link
Collaborator Author

bergmeister commented Sep 12, 2017

@kapilmb I renamed the switch to Fix and edited the markdown help file to fix the tests. I improved the code to detect and use the encoding. When test running it against the PowerShell repo, I found that it generally works fine but it converts some the psd1 files in ASCII to UTF8, which is probably due to the implementation of the EditableText class. However I think the current implementation should be sufficient due to delivered value.

@bergmeister bergmeister changed the title Add AutoFix switch parameter for 'File' parameter set to auto-correct warnings (#802) Add Fix switch parameter for 'File' parameter set to auto-correct warnings (#802) Sep 13, 2017
@PowerShell PowerShell deleted a comment from msftclas Sep 27, 2017
…rMarks overload.

Using StreamReader.Peek() instead of StreamReader.ReadToEnd() is sufficient to detect the encoding.
This improves the overall behaviour but when run against the PowerShell repo, it will still convert the ASCI psd1 files into UTF8 files. I think this is due to the implementation of the EditableText class.
@bergmeister
Copy link
Collaborator Author

@kapilmb What do you think about the current implementation?

@bergmeister
Copy link
Collaborator Author

@SteveL-MSFT : Is @kapilmb still maintaining this repo because it seems to have become stale?

@SteveL-MSFT
Copy link
Member

Yes, @kapilmb is still maintaining for now, but due to some resource shuffling internally, he may not be as available. @adityapatwardhan @JamesWTruher can you guys help out on this one?

@@ -1475,6 +1477,13 @@ public IEnumerable<DiagnosticRecord> AnalyzePath(string path, bool searchRecursi
this.BuildScriptPathList(path, searchRecursively, scriptFilePaths);
foreach (string scriptFilePath in scriptFilePaths)
{
if (fix)
Copy link
Member

Choose a reason for hiding this comment

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

Can some tests be added to test new code?

@@ -399,6 +399,23 @@ Accept pipeline input: False
Accept wildcard characters: False
```

### -Fix
Certain warnings contain a suggested fix in their DiagnosticRecord and therefore those warnings will be fixed automatically using this fix.
Copy link
Member

Choose a reason for hiding this comment

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

I suggest a bit of rewording to be like other switch parameters

Fixes certain warnings which contain a fix in their DiagnosticRecord.

### -Fix
Certain warnings contain a suggested fix in their DiagnosticRecord and therefore those warnings will be fixed automatically using this fix.

When you used Fix, Invoke-ScriptAnalyzer runs as usual but will apply the fixes before running the analysis. Please make sure that you have a backup of your files when using this switch. It tries to pre-server the file encoding but it is possible that a BOM gets added to the fixed files.
Copy link
Member

Choose a reason for hiding this comment

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

pre-server -> preserve.

@bergmeister
Copy link
Collaborator Author

bergmeister commented Nov 6, 2017

I applied your suggested changes but NuGet has a global outage at the moment (see here). Can you re-queue a build later again please?

@SteveL-MSFT
Copy link
Member

@bergmeister Nuget.org is back, I restarted your PR build

@bergmeister
Copy link
Collaborator Author

bergmeister commented Nov 6, 2017

Thanks Steve.
I improved the test in the meantime and downstreamed the latest changes. From what I can see in the build log is that the tests are run twice and the 2nd time the -Fix switch parameter is not present and therefore fails. I do not know all the details of the build but my local build for PowerShell Core and Windows PowerShell is OK and running the test file itself is fine but once I run Invoke-Pester I get similar failures where suddenly the -Fix is missing and it seems to me that this must be due to some other test before. I would appreciate help from someone that is more familiar with the whole build process because even the uploaded artifacts does not seem to have the -Fix switch on it (but I can see it in the help)

@kapilmb
Copy link

kapilmb commented Nov 8, 2017

@bergmeister Sorry I haven't been able to give any time here. I saw the test failures and it looks like you need to modify Tests/Engine/LibraryUsage.tests.ps1 for the tests to pass. I would recommend the following two things before considering this PR to be complete:

  • Please remove the fix parameter from the AnalyzePath and provide an alternate implementation of your logic. The method, AnalyzePath should only analyze and not be in the business of fixing. This would be in line with the coding best practice to have one function do only one thing.
  • We need to support ShouldProcess when using -Fix

…o a per process path and per file basis.

Propagating it further down would not make sense because then it would need to analyze all files, in this case SupportShouldContinue could be implemented in the future.
@bergmeister
Copy link
Collaborator Author

bergmeister commented Nov 9, 2017

@kapilmb Thanks for your pointers and review. I have implemented your suggestions and fixed the tests. Due to the many commits that I made, I think it would make sense to squash the merge btw.

…s were actually applied.

This helps especially because sometimes the encoding cannot be preserved (which is probably due to the EditableText implementation)
@kapilmb
Copy link

kapilmb commented Nov 15, 2017

@bergmeister Thanks for the changes. From a cursory glance things look complete, but I will look at it more carefully in the next 1-2 days and get back to you. We should be able to get this thing in soon. Thanks for your patience.

@kapilmb kapilmb merged commit 2056fe0 into PowerShell:development Nov 30, 2017
@bergmeister
Copy link
Collaborator Author

Thanks. :-) Do you know when the next Release is planned?

@JamesLear92
Copy link

So this was merged? I can see references to the -Fix Param in https://github.com/PowerShell/PSScriptAnalyzer readme, but I can't see the param in the module I downloaded today.

@bergmeister
Copy link
Collaborator Author

bergmeister commented Apr 6, 2018

@Omniusz It was merged into the development branch but is not released yet. The default view of the Github page shows you the development branch. For the documentation about the latest release, please refer to the master branch here: https://github.com/PowerShell/PSScriptAnalyzer/tree/master
P.S. We are expecting to release soon but I cannot say a date yet. If you want to I could give you a private preview build if you already want to use this new feature (the artifacts from the AppVeyor builds are not suitable for that unfortunately for unknown reasons)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants