diff --git a/.pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py b/.pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py index 351137c5e4..14f99330f6 100644 --- a/.pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py +++ b/.pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py @@ -6,9 +6,12 @@ import logging import os from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin +from edk2toollib.uefi.edk2.path_utilities import Edk2Path from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser from edk2toolext.environment.var_dict import VarDict +from edk2toollib.gitignore_parser import parse_gitignore_lines +from pathlib import Path class DscCompleteCheck(ICiBuildPlugin): @@ -71,38 +74,39 @@ class DscCompleteCheck(ICiBuildPlugin): # Get INF Files INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path) - INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath( - x) for x in INFFiles] # make edk2relative path so can compare with DSC # remove ignores - + ignored_paths = [] if "IgnoreInf" in pkgconfig: - for a in pkgconfig["IgnoreInf"]: - a = a.replace(os.sep, "/") + ignore_filter = parse_gitignore_lines( + pkgconfig["IgnoreInf"], + "DSC Complete Check Config", + os.path.dirname(abs_pkg_path)) + + # INFFiles must be a list of absolute paths + ignored_paths = list(filter(ignore_filter, INFFiles)) + for a in ignored_paths: try: tc.LogStdOut("Ignoring INF {0}".format(a)) INFFiles.remove(a) - except: + except Exception: tc.LogStdError( "DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a)) logging.info( "DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a)) + # make edk2relative path so can compare with DSC + INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(x) for x in INFFiles] + # DSC Parser - dp = DscParser() - dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath) - dp.SetPackagePaths(Edk2pathObj.PackagePathList) + dp = DscParser().SetEdk2Path(Edk2pathObj) dp.SetInputVars(environment.GetAllBuildKeyValues()) dp.ParseFile(wsr_dsc_path) # Check if INF in component section for INF in INFFiles: - if not any(INF.strip() in x for x in dp.ThreeMods) and \ - not any(INF.strip() in x for x in dp.SixMods) and \ - not any(INF.strip() in x for x in dp.OtherMods): - - infp = InfParser().SetBaseAbsPath(Edk2pathObj.WorkspacePath) - infp.SetPackagePaths(Edk2pathObj.PackagePathList) + if not DscCompleteCheck._module_in_dsc(INF, dp, Edk2pathObj): + infp = InfParser().SetEdk2Path(Edk2pathObj) infp.ParseFile(INF) if("MODULE_TYPE" not in infp.Dict): tc.LogStdOut( @@ -131,3 +135,22 @@ class DscCompleteCheck(ICiBuildPlugin): else: tc.SetSuccess() return overall_status + + @staticmethod + def _module_in_dsc(inf: str, dsc: DscParser, Edk2pathObj: Edk2Path) -> bool: + + """Checks if the given module (inf) is in the given dsc. + Args: + inf (str): The inf file to check for + dsc (DscParser): The parsed dsc file. + Edk2pathObj (Edk2Path): The path object capturing the workspace and package paths. + Returns: + bool: if the module is in the dsc. + """ + for module_type in (dsc.ThreeMods, dsc.SixMods, dsc.OtherMods): + for module in module_type: + if Path(module).is_absolute(): + module = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(module) + if inf in module: + return True + return False diff --git a/.pytool/Plugin/DscCompleteCheck/Readme.md b/.pytool/Plugin/DscCompleteCheck/Readme.md index 8aaa4f76ee..9f7291b747 100644 --- a/.pytool/Plugin/DscCompleteCheck/Readme.md +++ b/.pytool/Plugin/DscCompleteCheck/Readme.md @@ -29,4 +29,5 @@ Path to DSC to consider platform dsc ### IgnoreInf -Ignore error if Inf file is not listed in DSC file +A list of paths in git ignore syntax to ignore in the check. These can include directory and file paths. The path is +relative to the directory that contains the package.