]> git.proxmox.com Git - mirror_edk2.git/blob - .pytool/Plugin/DscCompleteCheck/DscCompleteCheck.py
e2485f570841b485bbfd02e4dbe6b92d4599e6ac
[mirror_edk2.git] / .pytool / Plugin / DscCompleteCheck / DscCompleteCheck.py
1 # @file DscCompleteCheck.py
2 #
3 # Copyright (c) Microsoft Corporation.
4 # SPDX-License-Identifier: BSD-2-Clause-Patent
5 ##
6 import logging
7 import os
8 from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
9 from edk2toollib.uefi.edk2.parsers.dsc_parser import DscParser
10 from edk2toollib.uefi.edk2.parsers.inf_parser import InfParser
11 from edk2toolext.environment.var_dict import VarDict
12
13
14 class DscCompleteCheck(ICiBuildPlugin):
15 """
16 A CiBuildPlugin that scans the package dsc file and confirms all modules (inf files) are
17 listed in the components sections.
18
19 Configuration options:
20 "DscCompleteCheck": {
21 "DscPath": "<path to dsc from root of pkg>"
22 "IgnoreInf": [] # Ignore INF if found in filesystem by not dsc
23 }
24 """
25
26 def GetTestName(self, packagename: str, environment: VarDict) -> tuple:
27 """ Provide the testcase name and classname for use in reporting
28
29 Args:
30 packagename: string containing name of package to build
31 environment: The VarDict for the test to run in
32 Returns:
33 a tuple containing the testcase name and the classname
34 (testcasename, classname)
35 testclassname: a descriptive string for the testcase can include whitespace
36 classname: should be patterned <packagename>.<plugin>.<optionally any unique condition>
37 """
38 return ("Check the " + packagename + " DSC for a being complete", packagename + ".DscCompleteCheck")
39
40 ##
41 # External function of plugin. This function is used to perform the task of the MuBuild Plugin
42 #
43 # - package is the edk2 path to package. This means workspace/packagepath relative.
44 # - edk2path object configured with workspace and packages path
45 # - PkgConfig Object (dict) for the pkg
46 # - VarDict containing the shell environment Build Vars
47 # - Plugin Manager Instance
48 # - Plugin Helper Obj Instance
49 # - Junit Logger
50 # - output_stream the StringIO output stream from this plugin via logging
51 def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
52 overall_status = 0
53
54 # Parse the config for required DscPath element
55 if "DscPath" not in pkgconfig:
56 tc.SetSkipped()
57 tc.LogStdError("DscPath not found in config file. Nothing to check.")
58 return -1
59
60 abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
61 abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip())
62 wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(abs_dsc_path)
63
64 if abs_dsc_path is None or wsr_dsc_path is "" or not os.path.isfile(abs_dsc_path):
65 tc.SetSkipped()
66 tc.LogStdError("Package Dsc not found")
67 return 0
68
69 # Get INF Files
70 INFFiles = self.WalkDirectoryForExtension([".inf"], abs_pkg_path)
71 INFFiles = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(x) for x in INFFiles] # make edk2relative path so can compare with DSC
72
73 # remove ignores
74
75 if "IgnoreInf" in pkgconfig:
76 for a in pkgconfig["IgnoreInf"]:
77 a = a.replace(os.sep, "/")
78 try:
79 tc.LogStdOut("Ignoring INF {0}".format(a))
80 INFFiles.remove(a)
81 except:
82 tc.LogStdError("DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
83 logging.info("DscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
84
85 # DSC Parser
86 dp = DscParser()
87 dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath)
88 dp.SetPackagePaths(Edk2pathObj.PackagePathList)
89 dp.SetInputVars(environment.GetAllBuildKeyValues())
90 dp.ParseFile(wsr_dsc_path)
91
92 # Check if INF in component section
93 for INF in INFFiles:
94 if not any(INF.strip() in x for x in dp.ThreeMods) and \
95 not any(INF.strip() in x for x in dp.SixMods) and \
96 not any(INF.strip() in x for x in dp.OtherMods):
97
98 infp = InfParser().SetBaseAbsPath(Edk2pathObj.WorkspacePath)
99 infp.SetPackagePaths(Edk2pathObj.PackagePathList)
100 infp.ParseFile(INF)
101 if("MODULE_TYPE" not in infp.Dict):
102 tc.LogStdOut("Ignoring INF. Missing key for MODULE_TYPE {0}".format(INF))
103 continue
104
105 if(infp.Dict["MODULE_TYPE"] == "HOST_APPLICATION"):
106 tc.LogStdOut("Ignoring INF. Module type is HOST_APPLICATION {0}".format(INF))
107 continue
108
109 logging.critical(INF + " not in " + wsr_dsc_path)
110 tc.LogStdError("{0} not in {1}".format(INF, wsr_dsc_path))
111 overall_status = overall_status + 1
112
113 # If XML object exists, add result
114 if overall_status is not 0:
115 tc.SetFailed("DscCompleteCheck {0} Failed. Errors {1}".format(wsr_dsc_path, overall_status), "CHECK_FAILED")
116 else:
117 tc.SetSuccess()
118 return overall_status