Reputation: 237
I need to run PyLint to validate my Python files code when building. The python files are under .pyproj (I use Python tools for Visual Studio 2015). How I can do that?
Update:
So far I have code like this:
<Target Name="PythonRunPyLint">
<PropertyGroup>
<PyLintWarningRegex><![CDATA[^(?<filename>.+?)\((?<line>\d+),(?<column>\d+)\): warning (?<msg_id>.+?): (?<message>.+?)$]]></PyLintWarningRegex>
</PropertyGroup>
<RunPythonCommand Target="pylint.lint"
TargetType="module"
Arguments=""--msg-template={abspath}({line},{column}): warning {msg_id}: {msg} [{C}:{symbol}]" -r n @(Compile, ' ')"
ExecuteIn="console"
WorkingDirectory="$(MSBuildProjectDirectory)"
WarningRegex="$(PyLintWarningRegex)"
RequiredPackages="pylint>=1.0.0">
<Output TaskParameter="ConsoleOutput" PropertyName="OutputText" />
<Output TaskParameter="ConsoleError" PropertyName="ErrorText" />
</RunPythonCommand>
</Target>
But when I run msbuild I get output and there's 0 warnings, why regex does not parse warnings (regex is taken from Microsoft.PythonTools.targets and it works when doing Tools > Run PyLint in Visual studio)?
C:\>msbuild TestPylint.pyproj /t:Build
Microsoft (R) Build Engine version 14.0.23107.0
Copyright (C) Microsoft Corporation. All rights reserved.
Build started 15/10/2015 20:10:26.
Project "C:\TestPylint.pyproj" on node 1 (Build target(s)).
PythonRunPyLint:
************* Module TestPylint
C:\TestPylint.py(2,0): warning C0304: Final newline missing [C:missing-final-newline]
C:\TestPylint.py(1,0): warning C0111: Missing module docstring [C:missing-docstring]
No config file found, using default configuration
Done Building Project "C:\TestPylint.pyproj" (Build target(s)) -- FAILED.
Build FAILED.
0 Warning(s)
0 Error(s)
Upvotes: 1
Views: 1373
Reputation: 36
The question is old, but I have spent some time on this issue. I suggest some improvements to the accepted answer by @Nmktronas, that solve the following problems:
Please see the comments in the code snippet.
<!-- Problem: PyLint is running only for Rebuild command, and never runs for Build command.
Solution: https://github.com/Microsoft/PTVS/issues/816: "The Outputs parameter of Target
node won't work, but if you add an item group called OutputFiles then we will compare
date/time stamps against those when deciding to build." -->
<ItemGroup>
<!-- Visible="false" prevents the file from showing in the Solution Window.-->
<OutputFiles Include="lint_output.txt"
Visible="false"/>
</ItemGroup>
<Target Name="BeforeBuild">
<!-- ExecuteIn="none" value prevents appearance of the Console window. -->
<RunPythonCommand Target="pylint.lint"
TargetType="module"
Arguments=""--msg-template={path}({line},{column}): warning: [{msg_id}{obj}] {msg}" -r n @(Compile, ' ')"
ExecuteIn="none"
WorkingDirectory="$(MSBuildProjectDirectory)"
RequiredPackages="pylint>=1.0.0"
ConsoleToMSBuild="true"
ContinueOnError="true">
<Output TaskParameter="ConsoleOutput" ItemName="OutputText" />
<Output TaskParameter="ConsoleError" PropertyName="ErrorText" />
</RunPythonCommand>
<WriteLinesToFile File="lint_output.txt"
Lines="@(OutputText)"
Overwrite="true"
Encoding="Unicode"/>
<Exec ContinueOnError="true"
IgnoreExitCode="true"
Command='type lint_output.txt'/>
</Target>
Upvotes: 0
Reputation: 119
A slight variation on the solution presented by @Nmktronas.
<Target Name="CoreCompile">
<ResolveEnvironment ContinueOnError="WarnAndContinue">
<Output TaskParameter="InterpreterPath" PropertyName="InterpreterPath" />
</ResolveEnvironment>
<Exec Condition="Exists($(InterpreterPath))"
Command="(set PYTHONPATH=$(SearchPath)) & "$(InterpreterPath)" -m pylint.lint "--msg-template={path}({line},{column}): warning: [{msg_id}{obj}] {msg}" -r n @(Compile, ' ')"
WorkingDirectory="$(MSBuildProjectDirectory)"
IgnoreExitCode="true" />
</Target>
Upvotes: 0
Reputation: 237
I ended up with the following code:
<Target Name="Build">
<RunPythonCommand Target="pylint.lint"
TargetType="module"
Arguments=""--msg-template={path}({line},{column}): warning: [{msg_id}{obj}] {msg}" -r n @(Compile, ' ')"
ExecuteIn="console"
WorkingDirectory="$(MSBuildProjectDirectory)"
RequiredPackages="pylint>=1.0.0"
ConsoleToMSBuild="true"
ContinueOnError="true">
<Output TaskParameter="ConsoleOutput" ItemName="OutputText" />
<Output TaskParameter="ConsoleError" PropertyName="ErrorText" />
</RunPythonCommand>
<WriteLinesToFile
File="lint_output.txt"
Lines="@(OutputText)"
Overwrite="true"
Encoding="Unicode"/>
<Exec ContinueOnError="true"
IgnoreExitCode="true"
Command='type lint_output.txt'/>
</Target>
Now msbuild TestPylint.pyproj /t:Build
counts errors/warnings also errors/warnings are shown on Visual Studio Error List window.
Task WriteLinesToFile is used because I did not found any other way for msbuild to recognize errors/warnings <Exec Command="echo $(OutputText)/>
(if OutputText is property) simply does not work!
Upvotes: 0
Reputation: 101555
It's not wired up out of the box, but you can add it to your project if you're so inclined. Locate Microsoft.PythonTools.targets
, and find <Target Name="PythonRunPyLintCommand" ...
inside. Copy that to your project, rename it to something like "PythonRunPyLint", and inside it replace CreatePythonCommandItem
with RunPythonCommand
. You might also have to remove some attributes on that element (basically any that MSBuild will complain do not exist), and remove the child <Output>
.
Then just start build with that target.
Upvotes: 1