使用 MsBuild 构建 .pyproj 时如何 运行 PyLint?

How to run PyLint for .pyproj when building it with MsBuild?

我需要 运行 PyLint 在构建时验证我的 Python 文件代码。 python 文件位于 .pyproj 下(我使用 Python 工具用于 Visual Studio 2015)。我该怎么做?

更新:

到目前为止我有这样的代码:

<Target Name="PythonRunPyLint">
    <PropertyGroup>
        <PyLintWarningRegex><![CDATA[^(?<filename>.+?)\((?<line>\d+),(?<column>\d+)\): warning (?<msg_id>.+?): (?<message>.+?)$]]></PyLintWarningRegex>
    </PropertyGroup>
    <RunPythonCommand Target="pylint.lint"
                             TargetType="module"
                             Arguments="&quot;--msg-template={abspath}({line},{column}): warning {msg_id}: {msg} [{C}:{symbol}]&quot; -r n @(Compile, ' ')"
                             ExecuteIn="console"
                             WorkingDirectory="$(MSBuildProjectDirectory)"
                             WarningRegex="$(PyLintWarningRegex)"
                             RequiredPackages="pylint&gt;=1.0.0"> 
        <Output TaskParameter="ConsoleOutput" PropertyName="OutputText" />
        <Output TaskParameter="ConsoleError" PropertyName="ErrorText" />
    </RunPythonCommand>
</Target>

但是当我 运行 msbuild 我得到输出并且有 0 个警告时,为什么正则表达式不解析警告(正则表达式取自 Microsoft.PythonTools.targets 并且它在执行工具 > 运行 时有效Visual studio)?

中的 PyLint
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)

它不是开箱即用的,但如果您愿意,可以将它添加到您的项目中。找到 Microsoft.PythonTools.targets,然后在里面找到 <Target Name="PythonRunPyLintCommand" ...。将其复制到您的项目中,将其重命名为 "PythonRunPyLint" 之类的名称,并在其中将 CreatePythonCommandItem 替换为 RunPythonCommand。您可能还必须删除该元素上的一些属性(基本上 MSBuild 会抱怨的任何属性都不存在),并删除子元素 <Output>.

然后使用该目标开始构建。

我得到了以下代码:

<Target Name="Build">
    <RunPythonCommand Target="pylint.lint"
                         TargetType="module"
                         Arguments="&quot;--msg-template={path}({line},{column}): warning: [{msg_id}{obj}] {msg}&quot; -r n @(Compile, ' ')"
                         ExecuteIn="console"
                         WorkingDirectory="$(MSBuildProjectDirectory)"
                         RequiredPackages="pylint&gt;=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>

现在 msbuild TestPylint.pyproj /t:Build 计数 errors/warnings 也 errors/warnings 显示在 Visual Studio 错误列表 window。

使用 Task WriteLinesToFile 是因为我没有找到任何其他方法让 msbuild 识别 errors/warnings <Exec Command="echo $(OutputText)/>(如果 OutputText 是 属性)根本不起作用!

@Nmktronas 提出的解决方案略有不同。

<Target Name="CoreCompile">
  <ResolveEnvironment ContinueOnError="WarnAndContinue">
    <Output TaskParameter="InterpreterPath" PropertyName="InterpreterPath" />
  </ResolveEnvironment>
  <Exec Condition="Exists($(InterpreterPath))"
        Command="(set PYTHONPATH=$(SearchPath)) &amp; &quot;$(InterpreterPath)&quot; -m pylint.lint &quot;--msg-template={path}({line},{column}): warning: [{msg_id}{obj}] {msg}&quot; -r n @(Compile, ' ')"
        WorkingDirectory="$(MSBuildProjectDirectory)"
        IgnoreExitCode="true" />
</Target>

这个问题很老了,但我已经在这个问题上花了一些时间。 我建议对@Nmktronas 接受的答案进行一些改进,以解决以下问题:

  1. PyLint 仅在重建命令之后运行,而不是在构建命令之后运行。
  2. 构建期间烦人的控制台 window 弹出窗口。

请查看代码段中的注释。

  <!-- 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="&quot;--msg-template={path}({line},{column}): warning: [{msg_id}{obj}] {msg}&quot; -r n @(Compile, ' ')"
                      ExecuteIn="none"
                      WorkingDirectory="$(MSBuildProjectDirectory)"
                      RequiredPackages="pylint&gt;=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>