在DeepSource配置中编写glob模式的提示

236 阅读4分钟

测试模式和排除模式是可选的,但却是配置文件的重要部分。 .deepsource.toml配置文件的重要部分。它们被写成glob模式。这些模式在减少DeepSource为项目提出的问题中的噪音和假阳性方面发挥着重要作用。

什么是Glob?

Glob或 "Shell Globing "是指编写glob模式来匹配文件系统中的文件的过程。Glob模式指定带有通配符的文件名集合。例如,Unix Bash shell命令rm -rftextfiles/*.txt 从textfiles文件夹中删除(rm)所有名称以.txt结尾的文件。在这里,* 是一个通配符,当与.txt 结合时,会产生*.txt ,这是一个glob模式。

除了匹配文件名之外,glob还可以用来匹配任意字符串(通配符匹配),比如? ,它可以匹配单个字符。

但是,由于我们的重点是编写测试文件和排除文件模式,所以我们将重点讨论通配符,例如*,**/ ,这些通配符广泛用于编写项目中匹配文件的 glob 模式。

  • * 匹配任何字符串,包括空字符串。就像上面的例子textfiles/*.txt ,其中'*'匹配所有名字以 "*"结尾的文件。
  • / 是一个常见的字符,被广泛用作路径分隔符。
  • ** 是被称为globstar的特征,它匹配所有的文件和零个或更多的目录和子目录。如果后面有一个 ,它只匹配目录和子目录。要以这种方式工作,它必须是路径部分中唯一的东西,例如,/Demo/**.py 就不能以这种方式工作。

DeepSource配置中的Globs

DeepSource配置中有两个部分可以使用glob模式:exclude_patternstest_patterns

  • exclude_patterns 这是一个glob模式的列表,在运行分析的时候应该被排除。这些模式应该是相对于版本库的根的。
  • test_patterns 是一个应该被标记为测试或包含测试文件的glob模式的列表。这些模式也应该是相对于版本库的根的。

默认情况下,DeepSource 会检查每个文件并对所有文件进行分析。在.deepsource.toml 中设置exclude_patternstest_patterns 配置,使 DeepSource 对你的代码有更多的了解。然后,DeepSource可以有选择地分析那些重要的文件。

一个快速的例子以及为什么你需要globs

在编写Python代码时,如果你不在test-patterns 中标记你的测试文件,DeepSource就会检测到assert语句的用法。assert 提供了一种简单的方法来检查一些条件并失败执行,对于开发人员来说,使用它来检查有效性是非常普遍的。但是,当Python解释器用-O (优化)标志调用时,断言语句会从字节码中删除。

因此,如果在生产代码中使用 assert 语句进行面向用户的验证,那么这个块根本就不会被执行 - 可能会打开一个安全漏洞。我们建议只在测试中使用断言语句。因此,为了避免DeepSource提出这样的问题,必须在test_patterns 中添加测试文件。

这里是一个配置样本,有一些测试和排除模式的例子。

version = 1

test_patterns = [
    "tests/**",
    "test_*.py",
    "*_test.rb\""
]

exclude_patterns = [
    "migrations/**",
    "*/examples/**"
]

[[analyzers]]
name = "python"
enabled = true

  [analyzers.meta]
  runtime_version = "3.x.x"

[[analyzers]]
name = "ruby"
enabled = true

缺少或错误的模式会增加噪音

让我们看看当我们错误地编写test_patterns时会发生什么。FOSSASIA在他们的一个名为open-event-server的项目中把测试文件模式写成了*/tests/** ,这导致了问题的总数达到了1700+左右。

Screenshot 1

但通过一个PR的简单修复,将测试文件模式更新为tests/** ,使得DeepSource提出的问题减少到1500个左右。

Screenshot 2


正确编写glob模式

现在让我们为测试和排除模式编写自己的glob模式。我们将使用Glob Tester工具来测试我们的模式,然后在配置中使用它们。

假设,我们有一个这样的项目结构。

src/
|---app.py
|---api/
|     |--- __init__.py
|     |--- middleware.py
|     |--- routes/
|          |--- auth/
|          |    |--- register.py
|          |    |--- login.py
|          |--- posts/
|          |    |--- get.py
|          |    |--- create.py
|          |--- comments/
|          |    |--- get.py
|          |    |--- create.py
|          |--- utils/
|          |    |--- security.py
|          |    |--- error.py
|--- models/
|    |--- comments.py
|    |--- posts.py
|    |--- users.py
|--- tests/
|     |--- __init__.py
|     |--- router/
|       |--- test_auth.py
|       |--- test_posts.py
|       |--- test_comments.py
|--- migrations/
|     |--- env.py
|     |--- scripts.py
|--- examples/
|     |--- example.py
|--- .gitignore
|--- Procfile
|--- README.md

去看这个Glob Tester Tool的例子,玩玩这个文件结构。

测试文件模式

这里所有重要的目录都是/src/ 的子目录。 匹配/src/tests/ 目录下所有文件的glob模式应该写成*/tests** - 其中*/ 表示匹配一个字符串,后面有一个路径分隔符。

因此,如果我们在DeepSource配置中使用*/tests/** 作为测试文件模式之一,DeepSource将在根目录下寻找一个名为tests 的目录,然后递归地寻找其中的所有文件。

Screenshot 3

使用Glob Tester工具根据glob模式寻找匹配的文件路径

带有这个值的配置将看起来像。

test_patterns = ["*/tests/**"]

提示:如果一个项目中有多个tests 子目录,同样的glob模式将不起作用。你的模式将变为**/tests/** -**/ ,在开始的时候,会递归地匹配所有子目录中出现的tests 目录。

排除文件模式

我们可以编写exclude_patterns 来忽略像examplesmigrations 这样的目录。你的glob模式将看起来像。

exclude_patterns = [
  "*/examples/**",
  "*/migrations/**"
]

完整的配置

将它们结合在一起,这就是.deepsource.toml 中的完整配置的样子。

version = 1

test_patterns = ["*/tests/**"]

exclude_patterns = [
"*/migrations/**",
"*/examples/**"
]

[[analyzers]]
name = "python"
enabled = true

[analyzers.meta]
runtime_version = "3.x.x"