Linter Bears-高级功能参考

通常情况下,毛线不是简单的工具。为了挤出最后一点功能和效率, @linter 提供了一些可供使用的高级功能。

为配置文件提供 generate_config

有时,工具需要配置文件才能运行。 @linter 通过重写 generate_config() .

@linter(executable='...')
class MyBear:
    @staticmethod
    def generate_config(filename, file):
        config_file = ("value1 = 1\n"
                       "value2 = 2")
        return config_file

此方法返回的字符串在调用 create_arguments() .

可以在内部访问临时配置文件的路径 create_arguments() 通过 config_file 参数:

@linter(executable='...')
class MyBear:
    @staticmethod
    def generate_config(filename, file):
        config_file = ("value1 = 1\n"
                       "value2 = 2")
        return config_file

    @staticmethod
    def create_arguments(filename, file, config_file):
        return "--use-config", config_file

如果你回来了 None ,则不会生成配置文件。显式返回的常见情况 None 是您希望为用户公开设置以使用其自己的特定于工具的配置的时候。如果用户指定了这样的配置文件,我们可以使用以下命令避免再次生成配置文件 generate_config 以降低I/O负载。

@linter(executable='...')
class MyBear:
    @staticmethod
    def generate_config(filename, file,
                        user_config: str='',
                        setting_a: bool=False):
        if user_config:
            return None
        else:
            return 'A={}'.format(setting_a)

    def create_arguments(filename, file, config_file,
                         user_config: str=''):
        return (filename, '--use-config',
                user_config if user_config else config_file)

备注

默认情况下,不会生成配置文件。

自定义处理功能,使用 process_output

里面 @linter 仅支持少数几种输出格式。并且它们不能针对不同的输出流进行组合。为了指定自己的输出解析/处理行为, process_output 可以重写。

@linter(executable='my_tool')
class MyBear:
    def process_output(self, output, filename, file):
        pass

这个 output 变量包含可执行文件的字符串输出。取决于您如何使用 use_stdoutuse_stderr 参数来自 @linteroutput 可以包含元组或纯字符串:如果 use_stdoutuse_stderr 都是 True ,则将元组放置在 (stdout, stderr) 。如果他们中只有一个是 True ,则传递一个字符串(包含所选的输出流)。

里面 process_output 您需要根据可执行输出生成结果。还可以组合内置功能。可以通过命名方案访问多个函数 process_output_<output-format> .

  • process_output_regex :使用正则表达式提取结果。

    @linter(executable='my_tool',
            use_stdout=False,
            use_stderr=True)
    class MyBear:
        # Assuming the tool puts some issue messages into stderr.
        def process_output(self, output, filename, file):
            # output is a string, as we activated just ``use_stderr``
            map = {'info': RESULT_SEVERITY.INFO,
                   'warn': RESULT_SEVERITY.NORMAL,
                   'error': RESULT_SEVERITY.MAJOR}
            regex = "(?P<line>\d+):(?P<message>(?P<severity>[WEI]).*)"
            yield from self.process_output_regex(stderr,
                                                 filename,
                                                 file,
                                                 regex,
                                                 map)
    

    用于结果的静电消息,而不是从可执行输出中抓取结果(通过 message 指定的regex组)也可以使用 result_message 参数。

  • process_output_corrected :使用已处理文件的更正版本提取结果(带补丁)。

    @linter(executable='my_tool',
            use_stdout=True,
            use_stderr=False)
    class MyBear:
        # Assuming the tool puts a corrected version of the file into stdout.
        def process_output(self, output, filename, file):
            # output is a string, as we activated just ``use_stdout``
            yield from self.process_output_corrected(
                                stdout,
                                filename,
                                file,
                                diff_severity=RESULT_SEVERITY.NORMAL,
                                diff_distance=2)
    

    这个 diff_distance 参数接受两个已更改行之间允许的未更改行数,以便将它们作为单个差异生成。如果 -1 如果给定,则每一次更改都将作为自己的不同而产生。

  • process_output_unified_diff :通过处理统一的差异提取结果(带面片)。

    @linter(executable='my_tool',
            use_stdout=True,
            use_stderr=True)
    class MyBear:
        # Assuming the tool puts a unified diff into stdout
        # and additional issue messages (that can't be fixed automatically)
        # into stderr, let's combine both streams!
        def process_output(self, output, filename, file):
            # output is now a tuple, as we activated both, ``use_stdout`` and
            # ``use_stderr``.
            stdout, stderr = output
            yield from self.process_output_unified_diff(stdout,
                                                        filename,
                                                        file)
            regex = "(?P<message>.*)"
            yield from self.process_output_regex(stderr,
                                                 filename,
                                                 file,
                                                 regex)
    

JSON输出也非常常见:

@linter(executable='my_tool')
class MyBear:
    def process_output(self, output, filename, file):
        for issue in json.loads(output):
            yield Result.from_values(origin=self,
                                     message=issue["message"],
                                     file=filename)

其他先决条件检查

@linter 支持在运行Bear之前进行额外的可执行文件检查,以及正常检查(检查可执行文件是否存在)。例如,这对于测试是否存在外部模块(如Java模块)很有用。

若要使用命令启用此附加检查,请使用 prerequisite_check_command 参数 @linter .

@linter(executable='...'
        prerequisite_check_command=('python3', '-c', 'import my_module'))
class MyBear:
    pass

如果默认错误消息不适合您,您还可以提供 prerequisite_check_fail_messageprerequisite_check_command .

@linter(executable='...'
        prerequisite_check_command=('python3', '-c', 'import my_module'),
        prerequisite_check_fail_message='my_module does not exist.')
class MyBear:
    pass