Lines Matching +full:if +full:- +full:no +full:- +full:files +full:- +full:found

5 # SPDX-License-Identifier: Apache-2.0
43 # errors if 'ignore_non_zero' is set to False (default: False). 'cwd' is the
52 if not ignore_non_zero and (cp.returncode or cp.stderr):
56 f"{cp.stdout.decode('utf-8')}\n"
58 f"{cp.stderr.decode('utf-8')}\n")
60 return cp.stdout.decode("utf-8").rstrip()
69 return git('rev-list',
70 f'--max-count={-1 if "." in refspec else 1}', refspec).split()
73 filter_arg = (f'--diff-filter={filter}',) if filter else ()
74 paths_arg = ('--', *paths) if paths else ()
75 out = git('diff', '--name-only', *filter_arg, COMMIT_RANGE, *paths_arg)
76 files = out.splitlines()
77 for file in list(files):
78 if not os.path.isfile(os.path.join(GIT_TOP, file)):
80 files.remove(file)
81 return files
95 description = f':{desc}' if desc else ''
99 (f'\nLine:{line}' if line else '') + \
100 (f'\nColumn:{col}' if col else '') + \
101 (f'\nEndLine:{end_line}' if end_line else '') + \
102 (f'\nEndColumn:{end_col}' if end_col else '')
103 msg = f'{file}' + (f':{line}' if line else '') + f' {msg_body}'
127 - The magic string "<zephyr-base>" can be used to refer to the
130 - The magic string "<git-top>" refers to the top-level repository
131 directory. This avoids running 'git' to find the top-level directory
202 Runs checkpatch and reports found issues
206 …doc = "See https://docs.zephyrproject.org/latest/contribute/guidelines.html#coding-style for more …
207 path_hint = "<git-top>"
211 if not os.path.exists(checkpatch):
212 self.skip(f'{checkpatch} not found')
215 if os.name == 'nt':
216 if not shutil.which('perl'):
217 …self.failure("Perl not installed - required for checkpatch.pl. Please install Perl or add to PATH.…
226 cmd.extend(['--mailback', '--no-tree', '-'])
227 diff = subprocess.Popen(('git', 'diff', '--no-ext-diff', COMMIT_RANGE),
239 output = ex.output.decode("utf-8")
247 if len(matches) > 500:
255 # If the regex has not matched add the whole output as a failure
256 if len(matches) == 0:
262 Check the board.yml files
266 path_hint = "<zephyr-base>"
272 if "vendor:" in line:
275 if vnd not in vendor_prefixes:
282 with open(os.path.join(ZEPHYR_BASE, "dts", "bindings", "vendor-prefixes.txt")) as fp:
285 if not line or line.startswith("#"):
291 self.error(f"Invalid line in vendor-prefixes.txt:\"{line}\".")
301 Check if clang-format reports any issues
304 …doc = "See https://docs.zephyrproject.org/latest/contribute/guidelines.html#clang-format for more …
305 path_hint = "<git-top>"
308 exe = f"clang-format-diff.{'exe' if platform.system() == 'Windows' else 'py'}"
311 if Path(file).suffix not in ['.c', '.h']:
314 diff = subprocess.Popen(('git', 'diff', '-U0', '--no-color', COMMIT_RANGE, '--', file),
318 subprocess.run((exe, '-p1'),
326 patchset = unidiff.PatchSet.from_string(ex.output, encoding="utf-8")
330 before = next(i for i,v in enumerate(hunk) if str(v).startswith(('-', '+')))
331 … after = next(i for i,v in enumerate(reversed(hunk)) if str(v).startswith(('-', '+')))
332 msg = "".join([str(l) for l in hunk[before:-after or None]])
336 "You may want to run clang-format on this change",
337 file, line=hunk.source_start + hunk.source_length - after,
343 Checks if we are introducing any unwanted properties in Devicetree Bindings.
347 path_hint = "<zephyr-base>"
357 Returns a list of dts/bindings/**/*.yaml files
362 if 'dts/bindings/' in file_name and file_name.endswith('.yaml'):
370 if 'required: false' in line:
384 path_hint = "<zephyr-base>"
386 # Top-level Kconfig file. The path can be relative to srctree (ZEPHYR_BASE).
413 # not a module nor a pip-installed Python utility
417 '--kconfig-out', modules_file,
418 '--sysbuild-kconfig-out', sysbuild_modules_file,
419 '--settings-out', settings_file]
424 self.error(ex.output.decode("utf-8"))
427 modules = [name for name in os.listdir(modules_dir) if
436 re.sub('[^a-zA-Z0-9]', '_', module).upper(),
447 # not a module nor a pip-installed Python utility
450 if os.path.exists(settings_file):
457 if line.startswith(f'"{root}_ROOT":'):
470 # not a module nor a pip-installed Python utility
481 '--kconfig-out', kconfig_dts_file, '--bindings-dirs']
488 self.error(ex.output.decode("utf-8"))
530 board_str = 'BOARD_' + re.sub(r"[^a-zA-Z0-9_]", "_", board.name).upper()
535 re.sub(r"[^a-zA-Z0-9_]", "_", qualifier)).upper()
584 Returns a kconfiglib.Kconfig object for the Kconfig files. We reuse
587 # Put the Kconfiglib path first to make sure no local Kconfiglib version is
590 if not os.path.exists(kconfig_path):
591 self.error(kconfig_path + " not found")
601 # Look up Kconfig files relative to ZEPHYR_BASE
628 # symbols within Kconfig files
661 # Warning: Needs to work with both --perl-regexp and the 're' module.
662 regex = r"^\s*(?:module\s*=\s*)([A-Z0-9_]+)\s*(?:#|$)"
665 grep_stdout = git("grep", "-I", "-h", "--perl-regexp", regex, "--",
679 Checks that there are no disallowed Kconfigs used in board/SoC defconfig files
688 # 'git grep --only-matching' would get rid of the surrounding context
695 # - ##, for token pasting (CONFIG_FOO_##X)
697 # - $, e.g. for CMake variable expansion (CONFIG_FOO_${VAR})
699 # - @, e.g. for CMakes's configure_file() (CONFIG_FOO_@VAR@)
701 # - {, e.g. for Python scripts ("CONFIG_FOO_{}_BAR".format(...)")
703 # - *, meant for comments like '#endif /* CONFIG_FOO_* */
711 # Warning: Needs to work with both --perl-regexp and the 're' module
712 regex_boards = r"\bCONFIG_[A-Z0-9_]+\b(?!\s*##|[$@{(.*])"
713 regex_socs = r"\bconfig\s+[A-Z0-9_]+$"
715 grep_stdout_boards = git("grep", "--line-number", "-I", "--null",
716 "--perl-regexp", regex_boards, "--", ":boards",
718 grep_stdout_socs = git("grep", "--line-number", "-I", "--null",
719 "--perl-regexp", regex_socs, "--", ":soc",
730 # Only check in Kconfig fragment files, references might exist in documentation
731 if re.match(disallowed_regex, sym_name) and (path[-len("conf"):] == "conf" or
732 path[-len("defconfig"):] == "defconfig"):
735 Found disallowed Kconfig symbol in board Kconfig files: CONFIG_{sym_name:35}
747 # Only check in Kconfig defconfig files
748 if re.match(disallowed_regex, sym_name) and "defconfig" in path:
751 Found disallowed Kconfig symbol in SoC Kconfig files: {sym_name:35}
756 # Returns a set() with the names of all defined Kconfig symbols (with no
763 # Warning: Needs to work with both --perl-regexp and the 're' module.
764 # (?:...) is a non-capturing group.
765 regex = r"^\s*(?:menu)?config\s*([A-Z0-9_]+)\s*(?:#|$)"
768 grep_stdout = git("grep", "-I", "-h", "--perl-regexp", regex, "--",
783 Checks that there aren't too many items in the top-level menu (which
792 # shown in the menuconfig (outside show-all mode).
793 if node.prompt:
797 if n_top_items > max_top_items:
799 Expected no more than {max_top_items} potentially visible items (items with
800 prompts) in the top-level Kconfig menu, found {n_top_items} items. If you're
805 # Checks that no symbols are (re)defined in defconfigs.
809 # pylint: disable=undefined-variable
810 if "defconfig" in node.filename and (node.prompt or node.help):
811 name = (node.item.name if node.item not in
814 Kconfig node '{name}' found with prompt or help in {node.filename}.
815 Options must not be defined in defconfig files.
823 # skip Kconfig nodes not in-tree (will present an absolute path)
824 if os.path.isabs(node.filename):
828 # pylint: disable=undefined-variable
831 if (not isinstance(node.item, kconfiglib.Symbol) or
837 if re.match(r"^[Ee]nable.*", node.prompt[0]):
845 # Checks that there are no pointless 'menuconfig' symbols without
846 # children in the Kconfig files
851 # pylint: disable=undefined-variable
856 if node.is_menuconfig and not node.list and \
861 if bad_mconfs:
863 Found pointless 'menuconfig' symbols without children. Use regular 'config'
865 https://docs.zephyrproject.org/latest/build/kconfig/tips.html#menuconfig-symbols.
872 Checks that there are no references to undefined Kconfig symbols within
873 the Kconfig files
876 if "undefined symbol" in warning)
878 if undef_ref_warnings:
890 # pylint: disable=undefined-variable
891 if isinstance(node.item, kconfiglib.Symbol) and node.item.name == "SOC":
898 if name not in soc_kconfig_names:
899 soc_name_warnings.append(f"soc name: {name} not found in CONFIG_SOC defaults.")
901 if soc_name_warnings:
911 Checks that there are no references to undefined Kconfig symbols
912 outside Kconfig files (any CONFIG_FOO where no FOO symbol exists)
921 # 'git grep --only-matching' would get rid of the surrounding context
928 # - ##, for token pasting (CONFIG_FOO_##X)
930 # - $, e.g. for CMake variable expansion (CONFIG_FOO_${VAR})
932 # - @, e.g. for CMakes's configure_file() (CONFIG_FOO_@VAR@)
934 # - {, e.g. for Python scripts ("CONFIG_FOO_{}_BAR".format(...)")
936 # - *, meant for comments like '#endif /* CONFIG_FOO_* */
943 # Warning: Needs to work with both --perl-regexp and the 're' module
944 regex = r"\b" + self.CONFIG_ + r"[A-Z0-9_]+\b(?!\s*##|[$@{(.*])"
948 grep_stdout = git("grep", "--line-number", "-I", "--null",
949 "--perl-regexp", regex, "--", ":!/doc/releases",
961 if sym_name not in defined_syms and \
963 not (sym_name.endswith("_MODULE") and sym_name[:-7] in defined_syms):
967 if not undef_to_locs:
980 Found references to undefined Kconfig symbols. If any of these are false
983 If the reference is for a comment like /* CONFIG_FOO_* */ (or
995 # zephyr-keep-sorted-start re(^\s+")
1018 "BOOT_SERIAL_BOOT_MODE", # Used in (sysbuild-based) test/
1020 "BOOT_SERIAL_CDC_ACM", # Used in (sysbuild-based) test
1021 "BOOT_SERIAL_ENTRANCE_GPIO", # Used in (sysbuild-based) test
1025 "BOOT_SHARE_DATA_BOOTINFO", # Used in (sysbuild-based) test
1036 "BOOT_VALIDATE_SLOT0", # Used in (sysbuild-based) test
1037 "BOOT_WATCHDOG_FEED", # Used in (sysbuild-based) test
1043 "CMD_CACHE", # Defined in U-Boot, mentioned in docs
1068 "LLVM_USE_LLD", # which are only included if LLVM is selected but
1070 # for example, if you are using GCC.
1074 "MCUBOOT_ACTION_HOOKS", # Used in (sysbuild-based) test
1075 "MCUBOOT_CLEANUP_ARM_CORE", # Used in (sysbuild-based) test
1081 "MCUBOOT_SERIAL", # Used in (sysbuild-based) test/
1094 "PSA_H", # This is used in config-psa.h as guard for the header file
1123 # zephyr-keep-sorted-stop
1129 Checks if we are introducing any new warnings/errors with Kconfig,
1142 Checks if we are introducing any new warnings/errors with Kconfig when no
1161 This ensures the board and SoC trees are fully self-contained and reusable.
1172 Checks if we are introducing any new warnings/errors with sysbuild Kconfig,
1182 # zephyr-keep-sorted-start re(^\s+")
1192 # zephyr-keep-sorted-stop
1198 Checks if we are introducing any new warnings/errors with sysbuild Kconfig,
1208 Checks if we are introducing any new warnings/errors with sysbuild Kconfig
1209 when no modules are available. Catches symbols used in the main repository
1217 Checks various nits in added/modified files. Doesn't check stuff that's
1221 …doc = "See https://docs.zephyrproject.org/latest/contribute/guidelines.html#coding-style for more …
1222 path_hint = "<git-top>"
1225 # Loop through added/modified files
1227 if "Kconfig" in fname:
1231 if fname.startswith("dts/bindings/"):
1234 if fname.endswith((".c", ".conf", ".cpp", ".dts", ".overlay",
1244 # Checks for a spammy copy-pasted header format
1246 with open(os.path.join(GIT_TOP, fname), encoding="utf-8") as f:
1249 # 'Kconfig - yada yada' has a copy-pasted redundant filename at the
1250 # top. This probably means all of the header was copy-pasted.
1251 if re.match(r"\s*#\s*(K|k)config[\w.-]*\s*-", contents):
1254 https://docs.zephyrproject.org/latest/build/kconfig/tips.html#header-comments-and-other-nits):
1259 # SPDX-License-Identifier: <License>
1263 Skip the "Kconfig - " part of the first line, since it's clear that the comment
1264 is about Kconfig from context. The "# Kconfig - " is what triggers this
1272 with open(os.path.join(GIT_TOP, fname), encoding="utf-8") as f:
1278 if match:
1287 with open(os.path.join(GIT_TOP, fname), encoding="utf-8") as f:
1288 if re.search(r"^\.\.\.", f.read(), re.MULTILINE):
1290 Redundant '...' document separator in {fname}. Binding YAML files are never
1291 concatenated together, so no document separators are needed.""")
1294 # Generic nits related to various source files
1296 with open(os.path.join(GIT_TOP, fname), encoding="utf-8") as f:
1299 if not contents.endswith("\n"):
1303 if contents.startswith("\n"):
1306 if contents.endswith("\n\n"):
1312 Checks for conflict markers or whitespace errors with git diff --check
1316 path_hint = "<git-top>"
1321 # Reason: `--check` is mutually exclusive with `--name-only` and `-s`
1325 # Ignore non-zero return status code
1326 # Reason: `git diff --check` sets the return code to the number of offending lines
1327 diff = git("diff", f"{shaidx}^!", "--check", ignore_non_zero=True)
1333 if len(offending_lines) > 0:
1343 …doc = "See https://docs.zephyrproject.org/latest/contribute/guidelines.html#commit-guidelines for …
1344 path_hint = "<git-top>"
1350 subprocess.run('gitlint --commits ' + COMMIT_RANGE,
1357 self.failure(ex.output.decode("utf-8"))
1362 Runs pylint on all .py files, with a limited set of checks enabled. The
1367 path_hint = "<git-top>"
1378 # List of files added/modified by the commit(s).
1379 files = get_files(filter="d")
1381 # Filter out everything but Python files. Keep filenames
1384 py_files = filter_py(GIT_TOP, files)
1385 if not py_files:
1389 if "PYTHONPATH" in python_environment:
1395 pylintcmd = ["pylint", "--output-format=json2", "--rcfile=" + pylintrc,
1396 "--load-plugins=argparse-checker"] + py_files
1406 output = ex.output.decode("utf-8")
1410 if m['messageId'][0] in ('F', 'E'):
1418 if len(messages) == 0:
1419 # If there are no specific messages add the whole output as a failure
1427 # Uses the python-magic library, so that we can detect Python
1428 # files that don't end in .py as well. python-magic is a frontend
1431 if (fname.endswith(".py") or
1433 mime=True) == "text/x-python")]
1438 Checks if Emails of author and signed-off messages are consistent.
1441 …doc = "See https://docs.zephyrproject.org/latest/contribute/guidelines.html#commit-guidelines for …
1442 # git rev-list and git log don't depend on the current (sub)directory
1444 path_hint = "<git-top>"
1449 'show', '-s', '--format=%an%n%ae%n%b', shaidx
1452 match_signoff = re.search(r"signed-off-by:\s(.*)", body,
1454 detailed_match = re.search(r"signed-off-by:\s(.*) <(.*)>", body,
1459 if auth_email.endswith("@users.noreply.github.com"):
1464 if not match_signoff:
1465 failures.append(f'{shaidx}: Missing signed-off-by line')
1468 failures.append(f"{shaidx}: Signed-off-by line ({signoff}) "
1473 "to match one of the signed-off-by entries.")
1475 if failures:
1481 Check that the diff contains no binary files.
1484 doc = "No binary files allowed."
1485 path_hint = "<git-top>"
1489 # svg files are always detected as binary, see .gitattributes
1492 for stat in git("diff", "--numstat", "--diff-filter=A",
1495 if added == "-" and deleted == "-":
1496 if (fname.startswith(BINARY_ALLOW_PATHS) and
1507 doc = "Check the size of image files."
1508 path_hint = "<git-top>"
1518 if not mime_type.startswith("image/"):
1524 if file.startswith("boards/"):
1527 if size > limit:
1538 path_hint = "<git-top>"
1544 if not os.path.exists(file):
1558 path_hint = "<git-top>"
1567 if os.path.exists(file):
1570 if not maintainers_file:
1576 if not manifest.is_active(project):
1579 if isinstance(project, ManifestProject):
1583 if area not in maintainers.areas:
1592 doc = "Check YAML files with YAMLLint."
1593 path_hint = "<git-top>"
1599 if Path(file).suffix not in ['.yaml', '.yml']:
1604 if file.startswith(".github/"):
1605 # Tweak few rules for workflow files.
1606 yaml_config.rules["line-length"] = False
1607 yaml_config.rules["truthy"]["allowed-values"].extend(['on', 'off'])
1609 yaml_config.rules["truthy"]["allowed-values"].extend(['yes', 'no'])
1623 doc = "Check Sphinx/reStructuredText files with sphinx-lint."
1624 path_hint = "<git-top>"
1626 # Checkers added/removed to sphinx-lint's default set
1627 DISABLE_CHECKERS = ["horizontal-tab", "missing-space-before-default-role"]
1628 ENABLE_CHECKERS = ["default-role"]
1632 if not file.endswith(".rst"):
1636 # sphinx-lint does not expose a public API so interaction is done via CLI
1638 … f"sphinx-lint -d {','.join(self.DISABLE_CHECKERS)} -e {','.join(self.ENABLE_CHECKERS)} {file}",
1647 for line in ex.output.decode("utf-8").splitlines():
1650 if match:
1666 path_hint = "<git-top>"
1668 MARKER = "zephyr-keep-sorted"
1674 if regex is None:
1681 if not line.strip():
1685 if regex:
1687 if not re.match(regex, line):
1690 if _test_indent(line):
1697 if line < last:
1702 return -1
1707 if not mime_type.startswith("text/"):
1713 start_marker = f"{self.MARKER}-start"
1714 stop_marker = f"{self.MARKER}-stop"
1720 if start_marker in line:
1721 if in_block:
1731 regex = match.group(1) if match else None
1733 if not in_block:
1740 if idx >= 0:
1741 desc = f"sorted block has out-of-order line at {start_line + idx}"
1747 if in_block:
1761 doc = "Check python files with ruff."
1762 path_hint = "<git-top>"
1766 if not file.endswith(".py"):
1771 f"ruff check --force-exclude --output-format=json {file}",
1779 output = ex.output.decode("utf-8")
1794 f"ruff format --force-exclude --diff {file}",
1806 Check that any text file is encoded in ascii or utf-8.
1809 doc = "Check the encoding of text files."
1810 path_hint = "<git-top>"
1812 ALLOWED_CHARSETS = ["us-ascii", "utf-8"]
1821 if not mime_type.startswith("text/"):
1825 if mime_type.rsplit('=')[-1] not in self.ALLOWED_CHARSETS:
1838 console.setFormatter(logging.Formatter('%(levelname)-8s: %(message)s'))
1854 if child not in subclasses:
1862 …https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#about-work…
1866 (f',line={res.line}' if res.line else '') + \
1867 (f',col={res.col}' if res.col else '') + \
1868 (f',endLine={res.end_line}' if res.end_line else '') + \
1869 (f',endColumn={res.end_col}' if res.end_col else '') + \
1875 if hint == "<zephyr-base>":
1877 elif hint == "<git-top>":
1888 parser.add_argument('-c', '--commits', default=default_range,
1891 parser.add_argument('-o', '--output', default="compliance.xml",
1894 parser.add_argument('-n', '--no-case-output', action="store_true",
1896 parser.add_argument('-l', '--list', action="store_true",
1898 parser.add_argument("-v", "--loglevel", choices=['DEBUG', 'INFO', 'WARNING',
1901 parser.add_argument('-m', '--module', action="append", default=[],
1904 parser.add_argument('-e', '--exclude-module', action="append", default=[],
1907 parser.add_argument('-j', '--previous-run', default=None,
1908 help='''Pre-load JUnit results in XML format
1910 parser.add_argument('--annotate', action="store_true",
1911 help="Print GitHub Actions-compatible annotations.")
1921 if not ZEPHYR_BASE:
1929 # The absolute path of the top-level git directory. Initialize it here so
1932 GIT_TOP = git("rev-parse", "--show-toplevel")
1934 # The commit range passed in --commit, e.g. "HEAD~3"
1942 if args.list:
1947 # Load saved test results from an earlier run, if requested
1948 if args.previous_run:
1949 if not os.path.exists(args.previous_run):
1951 # (the script is currently run multiple times by the ci-pipelines
1955 print(f"error: '{args.previous_run}' not found",
1971 # been --tests and --exclude-tests or the like, but it's awkward to
1974 if included and testcase.name.lower() not in included:
1977 if testcase.name.lower() in excluded:
1989 # Annotate if required
1990 if args.annotate:
1996 if args.output:
2007 if case.result:
2008 if case.is_skipped:
2013 # Some checks can produce no .result
2014 logging.info(f"No JUnit result for {case.name}")
2018 if n_fails:
2024 if args.no_case_output:
2033 if args.output:
2042 # pylint: disable=unused-import
2063 # Formats the command-line arguments in the iterable 'cmd' into a string,
2070 cmd = sys.argv[0] # Empty if missing
2071 if cmd:
2076 if __name__ == "__main__":