forked from platformio/platformio-core
Improved file filtering for the Static Analysis feature (#4570)
* Improved file filtering for the Static Analysis feature * Better handling of legacy "check_patterns" option * Rename "check_src_filter" to plural form to better represent functionality * Move to plural forms of filter variables
This commit is contained in:
1 parent
f2d206ca54
commit
d9ff250f82
8 files changed
+224
-76
No files matched your search
+156
-52
@@ -15,8 +15,8 @@
|
||||
# pylint: disable=redefined-outer-name
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from os.path import isfile, join
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -83,12 +83,12 @@ def check_dir(tmpdir_factory):
|
||||
|
||||
def count_defects(output):
|
||||
error, warning, style = 0, 0, 0
|
||||
for l in output.split("\n"):
|
||||
if "[high:error]" in l:
|
||||
for line in output.split("\n"):
|
||||
if "[high:error]" in line:
|
||||
error += 1
|
||||
elif "[medium:warning]" in l:
|
||||
elif "[medium:warning]" in line:
|
||||
warning += 1
|
||||
elif "[low:style]" in l:
|
||||
elif "[low:style]" in line:
|
||||
style += 1
|
||||
return error, warning, style
|
||||
|
||||
@@ -240,9 +240,9 @@ def test_check_includes_passed(clirunner, check_dir):
|
||||
result = clirunner.invoke(cmd_check, ["--project-dir", str(check_dir), "--verbose"])
|
||||
|
||||
inc_count = 0
|
||||
for l in result.output.split("\n"):
|
||||
if l.startswith("Includes:"):
|
||||
inc_count = l.count("-I")
|
||||
for line in result.output.split("\n"):
|
||||
if line.startswith("Includes:"):
|
||||
inc_count = line.count("-I")
|
||||
|
||||
# at least 1 include path for default mode
|
||||
assert inc_count > 0
|
||||
@@ -259,46 +259,6 @@ def test_check_silent_mode(clirunner, validate_cliresult, check_dir):
|
||||
assert style == 0
|
||||
|
||||
|
||||
def test_check_custom_pattern_absolute_path(
|
||||
clirunner, validate_cliresult, tmpdir_factory
|
||||
):
|
||||
project_dir = tmpdir_factory.mktemp("project")
|
||||
project_dir.join("platformio.ini").write(DEFAULT_CONFIG)
|
||||
|
||||
check_dir = tmpdir_factory.mktemp("custom_src_dir")
|
||||
check_dir.join("main.cpp").write(TEST_CODE)
|
||||
|
||||
result = clirunner.invoke(
|
||||
cmd_check, ["--project-dir", str(project_dir), "--pattern=" + str(check_dir)]
|
||||
)
|
||||
validate_cliresult(result)
|
||||
|
||||
errors, warnings, style = count_defects(result.output)
|
||||
|
||||
assert errors == EXPECTED_ERRORS
|
||||
assert warnings == EXPECTED_WARNINGS
|
||||
assert style == EXPECTED_STYLE
|
||||
|
||||
|
||||
def test_check_custom_pattern_relative_path(
|
||||
clirunner, validate_cliresult, tmpdir_factory
|
||||
):
|
||||
tmpdir = tmpdir_factory.mktemp("project")
|
||||
tmpdir.join("platformio.ini").write(DEFAULT_CONFIG)
|
||||
|
||||
tmpdir.mkdir("app").join("main.cpp").write(TEST_CODE)
|
||||
tmpdir.mkdir("prj").join("test.cpp").write(TEST_CODE)
|
||||
|
||||
result = clirunner.invoke(
|
||||
cmd_check, ["--project-dir", str(tmpdir), "--pattern=app", "--pattern=prj"]
|
||||
)
|
||||
validate_cliresult(result)
|
||||
|
||||
errors, warnings, style = count_defects(result.output)
|
||||
|
||||
assert errors + warnings + style == EXPECTED_DEFECTS * 2
|
||||
|
||||
|
||||
def test_check_no_source_files(clirunner, tmpdir):
|
||||
tmpdir.join("platformio.ini").write(DEFAULT_CONFIG)
|
||||
tmpdir.mkdir("src")
|
||||
@@ -427,7 +387,7 @@ R21.4 text.
|
||||
|
||||
validate_cliresult(result)
|
||||
assert "R21.3 Found MISRA defect" in result.output
|
||||
assert not isfile(join(str(check_dir), "src", "main.cpp.dump"))
|
||||
assert not os.path.isfile(os.path.join(str(check_dir), "src", "main.cpp.dump"))
|
||||
|
||||
|
||||
def test_check_fails_on_defects_only_with_flag(clirunner, validate_cliresult, tmpdir):
|
||||
@@ -607,10 +567,10 @@ framework = arduino
|
||||
validate_cliresult(result)
|
||||
|
||||
project_path = fs.to_unix_path(str(tmpdir))
|
||||
for l in result.output.split("\n"):
|
||||
if not l.startswith("Includes:"):
|
||||
for line in result.output.split("\n"):
|
||||
if not line.startswith("Includes:"):
|
||||
continue
|
||||
for inc in l.split(" "):
|
||||
for inc in line.split(" "):
|
||||
if inc.startswith("-I") and project_path not in inc:
|
||||
pytest.fail("Detected an include path from packages: " + inc)
|
||||
|
||||
@@ -656,3 +616,147 @@ def test_check_handles_spaces_in_paths(clirunner, validate_cliresult, tmpdir_fac
|
||||
default_result = clirunner.invoke(cmd_check, ["--project-dir", str(tmpdir)])
|
||||
|
||||
validate_cliresult(default_result)
|
||||
|
||||
|
||||
#
|
||||
# Files filtering functionality
|
||||
#
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"src_filter,number_of_checked_files",
|
||||
[
|
||||
(["+<src/app.cpp>"], 1),
|
||||
(["+<tests/*.cpp>"], 1),
|
||||
(["+<src>", "-<src/*.cpp>"], 2),
|
||||
(["-<*> +<src/main.cpp> +<src/uart/uart.cpp> +<src/spi/spi.cpp>"], 3),
|
||||
],
|
||||
ids=["Single file", "Glob pattern", "Exclude pattern", "Filter as string"],
|
||||
)
|
||||
def test_check_src_filter(
|
||||
clirunner,
|
||||
validate_cliresult,
|
||||
tmpdir_factory,
|
||||
src_filter,
|
||||
number_of_checked_files,
|
||||
):
|
||||
tmpdir = tmpdir_factory.mktemp("project")
|
||||
tmpdir.join("platformio.ini").write(DEFAULT_CONFIG)
|
||||
|
||||
src_dir = tmpdir.mkdir("src")
|
||||
src_dir.join("main.cpp").write(TEST_CODE)
|
||||
src_dir.join("app.cpp").write(TEST_CODE)
|
||||
src_dir.mkdir("uart").join("uart.cpp").write(TEST_CODE)
|
||||
src_dir.mkdir("spi").join("spi.cpp").write(TEST_CODE)
|
||||
tmpdir.mkdir("tests").join("test.cpp").write(TEST_CODE)
|
||||
|
||||
cmd_args = ["--project-dir", str(tmpdir)] + [
|
||||
"--src-filters=%s" % f for f in src_filter
|
||||
]
|
||||
|
||||
result = clirunner.invoke(cmd_check, cmd_args)
|
||||
validate_cliresult(result)
|
||||
|
||||
errors, warnings, style = count_defects(result.output)
|
||||
|
||||
assert errors + warnings + style == EXPECTED_DEFECTS * number_of_checked_files
|
||||
|
||||
|
||||
def test_check_src_filter_from_config(clirunner, validate_cliresult, tmpdir_factory):
|
||||
tmpdir = tmpdir_factory.mktemp("project")
|
||||
|
||||
config = (
|
||||
DEFAULT_CONFIG
|
||||
+ """
|
||||
check_src_filters =
|
||||
+<src/spi/*.c*>
|
||||
+<tests/test.cpp>
|
||||
"""
|
||||
)
|
||||
tmpdir.join("platformio.ini").write(config)
|
||||
|
||||
src_dir = tmpdir.mkdir("src")
|
||||
src_dir.join("main.cpp").write(TEST_CODE)
|
||||
src_dir.mkdir("spi").join("spi.cpp").write(TEST_CODE)
|
||||
tmpdir.mkdir("tests").join("test.cpp").write(TEST_CODE)
|
||||
|
||||
result = clirunner.invoke(cmd_check, ["--project-dir", str(tmpdir)])
|
||||
validate_cliresult(result)
|
||||
|
||||
errors, warnings, style = count_defects(result.output)
|
||||
|
||||
assert errors + warnings + style == EXPECTED_DEFECTS * 2
|
||||
assert "main.cpp" not in result.output
|
||||
|
||||
|
||||
def test_check_custom_pattern_absolute_path_legacy(
|
||||
clirunner, validate_cliresult, tmpdir_factory
|
||||
):
|
||||
project_dir = tmpdir_factory.mktemp("project")
|
||||
project_dir.join("platformio.ini").write(DEFAULT_CONFIG)
|
||||
|
||||
check_dir = tmpdir_factory.mktemp("custom_src_dir")
|
||||
check_dir.join("main.cpp").write(TEST_CODE)
|
||||
|
||||
result = clirunner.invoke(
|
||||
cmd_check, ["--project-dir", str(project_dir), "--pattern=" + str(check_dir)]
|
||||
)
|
||||
|
||||
validate_cliresult(result)
|
||||
|
||||
errors, warnings, style = count_defects(result.output)
|
||||
|
||||
assert errors == EXPECTED_ERRORS
|
||||
assert warnings == EXPECTED_WARNINGS
|
||||
assert style == EXPECTED_STYLE
|
||||
|
||||
|
||||
def test_check_custom_pattern_relative_path_legacy(
|
||||
clirunner, validate_cliresult, tmpdir_factory
|
||||
):
|
||||
tmpdir = tmpdir_factory.mktemp("project")
|
||||
tmpdir.join("platformio.ini").write(DEFAULT_CONFIG)
|
||||
|
||||
src_dir = tmpdir.mkdir("src")
|
||||
src_dir.join("main.cpp").write(TEST_CODE)
|
||||
src_dir.mkdir("uart").join("uart.cpp").write(TEST_CODE)
|
||||
src_dir.mkdir("spi").join("spi.cpp").write(TEST_CODE)
|
||||
|
||||
result = clirunner.invoke(
|
||||
cmd_check,
|
||||
["--project-dir", str(tmpdir), "--pattern=src/uart", "--pattern=src/spi"],
|
||||
)
|
||||
validate_cliresult(result)
|
||||
|
||||
errors, warnings, style = count_defects(result.output)
|
||||
|
||||
assert errors + warnings + style == EXPECTED_DEFECTS * 2
|
||||
|
||||
|
||||
def test_check_src_filter_from_config_legacy(
|
||||
clirunner, validate_cliresult, tmpdir_factory
|
||||
):
|
||||
tmpdir = tmpdir_factory.mktemp("project")
|
||||
|
||||
config = (
|
||||
DEFAULT_CONFIG
|
||||
+ """
|
||||
check_patterns =
|
||||
src/spi/*.c*
|
||||
tests/test.cpp
|
||||
"""
|
||||
)
|
||||
tmpdir.join("platformio.ini").write(config)
|
||||
|
||||
src_dir = tmpdir.mkdir("src")
|
||||
src_dir.join("main.cpp").write(TEST_CODE)
|
||||
src_dir.mkdir("spi").join("spi.cpp").write(TEST_CODE)
|
||||
tmpdir.mkdir("tests").join("test.cpp").write(TEST_CODE)
|
||||
|
||||
result = clirunner.invoke(cmd_check, ["--project-dir", str(tmpdir)])
|
||||
validate_cliresult(result)
|
||||
|
||||
errors, warnings, style = count_defects(result.output)
|
||||
|
||||
assert errors + warnings + style == EXPECTED_DEFECTS * 2
|
||||
assert "main.cpp" not in result.output
|
||||
Reference in new issue
Block a user