def _does_pkg_depend_on_package(self, package_to_eval: str, support_package: str) -> bool: ''' return if any module in package_to_eval depends on public files defined in support_package''' # get filesystem path of package_to_eval abs_pkg_path = self.edk2_path_obj.GetAbsolutePathOnThisSytemFromEdk2RelativePath( package_to_eval) # loop thru all inf files in the package inf_files = self._walk_dir_for_filetypes([".inf"], abs_pkg_path) # compare if support_pkg in packages section # For each INF file for f in inf_files: ip = InfParser() ip.SetBaseAbsPath( self.edk2_path_obj.WorkspacePath).SetPackagePaths( self.edk2_path_obj.PackagePathList).ParseFile(f) for p in ip.PackagesUsed: if p.startswith(support_package): self.logger.info( f"Module: {f} depends on package {support_package}") return True # if never found return False return False
def parse_guids_from_inf(filename: str) -> list: """ find the module guid in an Edk2 inf file filename: abspath to inf file """ inf = InfParser() inf.ParseFile(filename) try: return [ GuidListEntry(inf.Dict["BASE_NAME"], inf.Dict["FILE_GUID"].upper(), filename) ] except: logging.warning("Failed to find info from INF file: " + filename) return []
def ModuleHashCal(path): sourcefileList = [] binaryfileList = [] hash_obj = hashlib.md5() # Find the specific line of Sources section folderpath = os.path.dirname(path) if os.path.isdir(path): # Collect all files in this folder to the list for subdir, _, files in os.walk(path): for file in files: sourcefileList.append(os.path.join(subdir, file)) else: sourcefileList.append(path) if path.lower().endswith(".inf") and os.path.isfile(path): # Use InfParser to parse sources section ip = InfParser() ip.ParseFile(path) # Add all referenced source files in addition to our inf file list for source in ip.Sources: sourcefileList.append(os.path.normpath(os.path.join(folderpath, source))) # Add all referenced binary files to our binary file list for binary in ip.Binaries: binaryfileList.append(os.path.normpath(os.path.join(folderpath, binary))) for sfile in sourcefileList: #print('Calculated: %s' %(sfile)) #Debug only with open(sfile, 'rb') as entry: # replace \r\n with \n to take care of line terminators hash_obj.update(entry.read().replace(b'\r\n', b'\n')) for bfile in binaryfileList: #print('Calculated: %s' %(bfile)) #Debug only with open(bfile, 'rb') as entry: hash_obj.update(entry.read()) result = hash_obj.hexdigest() return result
def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None): overall_status = 0 # Get current platform abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath( packagename) # 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 Ignore List # Remove ignored INFs if "IgnoreInf" in pkgconfig: for a in pkgconfig["IgnoreInf"]: a = a.replace( os.sep, "/" ) ## convert path sep in case ignore list is bad. Can't change case try: INFFiles.remove(a) tc.LogStdOut("IgnoreInf {0}".format(a)) except: logging.info( "DependencyConfig.IgnoreInf -> {0} not found in filesystem. Invalid ignore file" .format(a)) tc.LogStdError( "DependencyConfig.IgnoreInf -> {0} not found in filesystem. Invalid ignore file" .format(a)) # Get the AccpetableDependencies list if "AcceptableDependencies" not in pkgconfig: logging.info( "DependencyCheck Skipped. No Acceptable Dependencies defined." ) tc.LogStdOut( "DependencyCheck Skipped. No Acceptable Dependencies defined." ) tc.SetSkipped() return -1 # Log dependencies for k in pkgconfig.keys(): if k.startswith("AcceptableDependencies"): pkgstring = "\n".join(pkgconfig[k]) if ("-" in k): _, _, mod_type = k.partition("-") tc.LogStdOut( f"Additional dependencies for MODULE_TYPE {mod_type}:\n {pkgstring}" ) else: tc.LogStdOut(f"Acceptable Dependencies:\n {pkgstring}") # For each INF file for file in INFFiles: ip = InfParser() logging.debug("Parsing " + file) ip.SetBaseAbsPath(Edk2pathObj.WorkspacePath).SetPackagePaths( Edk2pathObj.PackagePathList).ParseFile(file) if ("MODULE_TYPE" not in ip.Dict): tc.LogStdOut( "Ignoring INF. Missing key for MODULE_TYPE {0}".format( file)) continue mod_type = ip.Dict["MODULE_TYPE"].upper() for p in ip.PackagesUsed: if p not in pkgconfig["AcceptableDependencies"]: # If not in the main acceptable dependencies list then check module specific mod_specific_key = "AcceptableDependencies-" + mod_type if mod_specific_key in pkgconfig and p in pkgconfig[ mod_specific_key]: continue logging.error( "Dependency Check: Invalid Dependency INF: {0} depends on pkg {1}" .format(file, p)) tc.LogStdError( "Dependency Check: Invalid Dependency INF: {0} depends on pkg {1}" .format(file, p)) overall_status += 1 # If XML object exists, add results if overall_status != 0: tc.SetFailed("Failed with {0} errors".format(overall_status), "DEPENDENCYCHECK_FAILED") else: tc.SetSuccess() return overall_status
def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None): overall_status = 0 # Parse the config for required DscPath element if "DscPath" not in pkgconfig: tc.SetSkipped() tc.LogStdError( "DscPath not found in config file. Nothing to check.") return -1 abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath( packagename) abs_dsc_path = os.path.join(abs_pkg_path, pkgconfig["DscPath"].strip()) wsr_dsc_path = Edk2pathObj.GetEdk2RelativePathFromAbsolutePath( abs_dsc_path) if abs_dsc_path is None or wsr_dsc_path == "" or not os.path.isfile( abs_dsc_path): tc.SetSkipped() tc.LogStdError("Package Host Unit Test Dsc not found") return 0 # 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 if "IgnoreInf" in pkgconfig: for a in pkgconfig["IgnoreInf"]: a = a.replace(os.sep, "/") try: tc.LogStdOut("Ignoring INF {0}".format(a)) INFFiles.remove(a) except: tc.LogStdError( "HostUnitTestDscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file" .format(a)) logging.info( "HostUnitTestDscCompleteCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file" .format(a)) # DSC Parser dp = DscParser() dp.SetBaseAbsPath(Edk2pathObj.WorkspacePath) dp.SetPackagePaths(Edk2pathObj.PackagePathList) 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) infp.ParseFile(INF) if ("MODULE_TYPE" not in infp.Dict): tc.LogStdOut( "Ignoring INF. Missing key for MODULE_TYPE {0}".format( INF)) continue if (infp.Dict["MODULE_TYPE"] == "HOST_APPLICATION"): # should compile test a library that is declared type HOST_APPLICATION pass elif len(infp.SupportedPhases) > 0 and \ "HOST_APPLICATION" in infp.SupportedPhases: # should compile test a library that supports HOST_APPLICATION but # require it to be an explicit opt-in pass else: tc.LogStdOut( "Ignoring INF. MODULE_TYPE or suppored phases not HOST_APPLICATION {0}" .format(INF)) continue logging.critical(INF + " not in " + wsr_dsc_path) tc.LogStdError("{0} not in {1}".format(INF, wsr_dsc_path)) overall_status = overall_status + 1 # If XML object exists, add result if overall_status != 0: tc.SetFailed( "HostUnitTestDscCompleteCheck {0} Failed. Errors {1}".format( wsr_dsc_path, overall_status), "CHECK_FAILED") else: tc.SetSuccess() return overall_status