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 powershell/PSScriptAnalyzerBear #1967

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

userzimmermann
Copy link
Member

While attending @PPOSHGROUP's https://www.meetup.com/Polish-PowerShell-Group-PPoSh/events/241810275/ I realized that we haven't grown any powerBear for analyzing PowerShell code yet 😨 How do we ever want to get really accepted by the Windows community w/o the PSScriptAnalyzerBear? Here it is! And needs some mapping to all the https://github.com/PowerShell/PSScriptAnalyzer rules :D And tests of course! So there is still some work left to do...

@mgr32 Hi :) I was talking about coala and PS integration with @mczerniawski and he said you might be interested in such stuff ;) Are there maybe even more PS code analysis tools worth integrating?

cc @sils

@userzimmermann
Copy link
Member Author

powerBears CAN_FIX! I just found out that PSScriptAnalyzer can also suggest corrections :) So I extended the bear results with diffs generated from those suggestions

@userzimmermann userzimmermann force-pushed the zimmermann/powerbear branch 2 times, most recently from 264f35a to 860eee9 Compare August 1, 2017 23:19
@mgr32
Copy link

mgr32 commented Aug 2, 2017

Hi @userzimmermann, thanks for letting me know about coala, I've been a long-time user of SonarQube (but it doesn't have plugin for Powershell) 😃 As for other PS analysis tools I had been using ScriptCop, but I believe it's not maintained any more, so I would stick with PSScriptAnalyzer.

', '.join('{}={}'.format(name, name)
for name in rules)),
{'func': self.func},
doc=self.func.__doc__, __module__ = __name__)
Copy link
Collaborator

Choose a reason for hiding this comment

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

E251 unexpected spaces around keyword / parameter equals'

PycodestyleBear (E251), severity NORMAL, section autopep8.

', '.join('{}={}'.format(name, name)
for name in rules)),
{'func': self.func},
doc=self.func.__doc__, __module__ = __name__)
Copy link
Collaborator

Choose a reason for hiding this comment

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

E251 unexpected spaces around keyword / parameter equals'

PycodestyleBear (E251), severity NORMAL, section autopep8.

', '.join('{}={}'.format(name, name)
for name in rules)),
{'func': self.func},
doc=self.func.__doc__, __module__ = __name__)
Copy link
Collaborator

Choose a reason for hiding this comment

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

The code does not comply to PEP8.

PEP8Bear, severity NORMAL, section autopep8.

The issue can be fixed by applying the following patch:

--- a/bears/powershell/PSScriptAnalyzerBear.py
+++ b/bears/powershell/PSScriptAnalyzerBear.py
@@ -76,7 +76,7 @@
                     ', '.join('{}={}'.format(name, name)
                               for name in rules)),
             {'func': self.func},
-            doc=self.func.__doc__, __module__ = __name__)
+            doc=self.func.__doc__, __module__=__name__)
         # ... so they need to be implicitly added afterwards
         caller.__annotations__ = {name: bool for name in rules}
         caller.__defaults__ = (True, ) * len(rules)

@userzimmermann
Copy link
Member Author

@Makman2 I added this @Rulified for automagically turning all PSScriptAnalyzer rules into Bear settings. I know this purely dynamical approach is not a good solution for a release installation. But what do you anyway think about generalizing this? And then creating some static bundled setting definitions on building bears releases from it... For this case maybe looking like:

@linter(executable='powershell', settings={name: (bool, True) for name in rules()})
class PSScriptAnalyzerBear:
    ...
    # @linter can create the wrapper here or we extend the settings discovery routines
    @staticmethod
    def create_arguments(filename, file, config_file, **rules):
        ...

cc @sils @jayvdb

@userzimmermann
Copy link
Member Author

@mgr32 Thanks for your response :) Already tried coala in the meantime? ;) The nice advantages over SonarQube are the simple extensibility for new languages/tools, as you can see it here for PSScriptAnalyzer, and the CI integration with GitHub/Lab via @gitmate-bot which makes those nice PR comments like above in #1967 (review) and blocks the PR from getting merged until cleaned up... If you have further ideas or remarks regarding this PR or coala in general, please let us know :)

Also @mczerniawski @DomBros @bielawb ... If anything comes to your mind regarding this ... Can't wait to read it ;)

@userzimmermann userzimmermann requested a review from Makman2 August 2, 2017 19:44
@Makman2
Copy link
Member

Makman2 commented Aug 2, 2017

@Rulify looks promising. However where's the advantage over inlining rules() now into the function signature of create_arguments? Often parameters are processed further.
Also when having generate_config and create_arguments together, isn't this slightly overhead to pass the full list of rules/arguments to both functions?

@userzimmermann
Copy link
Member Author

@Makman2 I hope I got you right ;) There just doesn't seem to be another way to define Bear settings than adding them as parameters to create_arguments, or to run in the non-@linter-case. Correct me please! :P So if you want to create settings programmatically, you have do such kinds of hacks again and again. That's why I would like to create some generic API for programmatically defining them. The Bear-developer-defined create_arguments and generate_config methods then only have **settings and don't need additional @decorators

@Makman2
Copy link
Member

Makman2 commented Aug 4, 2017

Actually you can override get_metadata which is exactly doing this. coala takes the information to see what settings are required and optional and passes them to run. linter defines some additional "private" functions that further delegate those parameters to the create_arguments, process_output and generate_config functions: https://github.com/coala/coala/blob/master/coalib/bearlib/abstractions/Linter.py#L228-L253

We could make those public and allow to modify those, so you can define parameters like you want. But I want to be sure that this is a good thing to do ;)

However, I'm not sure that what you try to achieve for this bear specifically is a good approach. If you have different versions of PSScriptAnalyzer (not sure how powershell includes this commandlet), the bear signature changes. This is imo not desired, and we should have a fixed and static list of arguments coala supports. Also we are able to adapt style/rule names to our naming scheme (instead of taking them directly from powershell).

@userzimmermann
Copy link
Member Author

userzimmermann commented Aug 4, 2017

@Makman2 Thanks! The get_metadata override is a good idea :)

If you have different versions of PSScriptAnalyzer (not sure how powershell includes this commandlet), the bear signature changes.

This is exactly what I was referring to with "I know this purely dynamical approach is not a good solution for a release installation." And with the solution approach "And then creating some static bundled setting definitions on building bears releases from it..." we could always roll out the same pre-defined settings based on the linter version in our build system

This is imo not desired, and we should have a fixed and static list of arguments coala supports. Also we are able to adapt style/rule names to our naming scheme (instead of taking them directly from powershell).

Why reinventing the wheel? And we don't have a real naming scheme for bear settings. Every linter bear developer creates them on their own, mostly manually resembling the tool's native options. Of course! Why reinventing the wheel? ;) The tool users are used to those options. And this is usually done once. Haven't seen some pull request like Update ...Bear settings for new linter version. There is usually no maintenance to keep up with linter development going on. And the number of PSScriptAnalyzer rules is huge! So a (semi-)automatic approach actually seems beneficial to me. I can of course decamelize the PSScriptAnalyzer rule names and remove the PS prefixes, so that we have for example align_assignment_statement instead of PSAlignAssignmentStatement

All that hopefully changes with aspects... Then we really have to think about the integration of linter options and need to keep the aspects<-->tool-options relations up to date

@Makman2
Copy link
Member

Makman2 commented Aug 4, 2017

Why reinventing the wheel? And we don't have a real naming scheme for bear settings.

Yes we actually have ongoing efforts to unify setting names to include for example prefixes like prohibit, enforce, allow etc. Also between different bears having same setting names for same things is quite important imo.

Another thing are the type annotations: There are settings which are boolean, some which are string, and some are integers. If it's possible to extract this information out of the documentation texts, cool. If not we can only handcraft those ;) It's technically not necessary to annotate the types as we directly pass the settings to the linter, however it's valuable documentation for the user.

It's not that I want to turn down the idea, I'm just really not sure if it's the right direction for us to go.
CC @sils @jayvdb, would like some opinions here^^

@jayvdb
Copy link
Member

jayvdb commented Aug 4, 2017

IMO this is not helpful. We need precise versions of upstream tools , managed with package managers.
And we need to test each new release of a tool before pushing it downstream to users, and update the settings.

@userzimmermann
Copy link
Member Author

userzimmermann commented Aug 4, 2017

@jayvdb Exactly my ideas... I don't see any contradiction :) I only want to additionally generate the settings from that same precise version of PSScriptAnalyzer to be used in our build system and store them in the bears package. Because it's so simple in this case! Or I just generate the Python code ;) Instead of manually mapping those 51 rules. And for managing the dependency, I will add a PSRequirement or PowerShellRequirement class to dependency_management ... The WIP: here was not intended as short-term status ;)

@Makman2

There are settings which are boolean, some which are string, and some are integers. If it's possible to extract this information out of the documentation texts, cool. If not we can only handcraft those ;)

Of course! Automation where possible. Handcraft where needed. That's obvious ;)

@userzimmermann userzimmermann requested a review from jayvdb August 4, 2017 15:18
@jayvdb
Copy link
Member

jayvdb commented Aug 4, 2017

@userzimmermann , how are you going to automatically map those to aspects?

And we dont want PSScriptAnalyzer based naming; we have consistent naming for common concepts.

You'll end up with a custom parser that is quite complex, and most importantly that parser doesnt belong in the bear. Put it in a .ci script which checks the linter output to identify new settings not supported by the bear yet, and then maybe recommends the change needed to the bear.

@userzimmermann
Copy link
Member Author

@jayvdb I didn't write anything about automatic mapping to aspects... only settings

But it seems like manual adjustments are needed... So it looks like we could need some interactive tool-options<-->settings mapping assistant... For the development process... Something the bearship could offer... Should offer! Thanks for making me get this idea! :D That's going to be a great WIP ;)

@userzimmermann userzimmermann mentioned this pull request Nov 7, 2017
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

5 participants