def Go(self): workspace_path = self.GetWorkspaceRoot() self.edk2_path_obj = path_utilities.Edk2Path(workspace_path, []) self.logger = logging.getLogger("edk2_pr_eval") actualPackagesDict = self.get_packages_to_build( self.requested_package_list) # # Report the packages that need to be built # self.logger.log(edk2_logging.SECTION, "Output Results") self.logger.critical("Need to Build:") if len(actualPackagesDict.keys()) > 0: max_pkg_width = max(len(t) for t in actualPackagesDict.keys()) for key, value in actualPackagesDict.items(): self.logger.critical(f"{key:{max_pkg_width}} Reason: {value}") else: self.logger.critical("None") # # If requested thru cmd line write to std out in defined format # This enabled CI pipelines # if self.output_csv_format_string is not None: pkgcsv = ",".join([x for x in actualPackagesDict.keys()]) print(self.output_csv_format_string.format(pkgcsv=pkgcsv)) if self.output_count_format_string is not None: pkgcount = len(actualPackagesDict.keys()) print(self.output_count_format_string.format(pkgcount=pkgcount)) return 0
def __init__(self, filepath, ws, packagepathcsv, protectedWordsDict): self.PlatformName = "" self.DscPath = "" self.FdfPath = "" self.BuildOutputDir = "" self.ReportFile = filepath self.Modules = {} # fill this in with objects of ModuleSummary type self._ReportContents = "" self._Regions = [] # fill this in with tuple (type, start, end) self.Workspace = ws # needs to contain the trailing slash self.PackagePathList = [] for a in packagepathcsv.split(","): a = a.strip() if (len(a) > 0): self.PackagePathList.append(a) self.ProtectedWords = protectedWordsDict self.PathConverter = pu.Edk2Path(self.Workspace, self.PackagePathList)
def Go(self): # create path obj for resolving paths. Since PR eval is run early to determine if a build is # impacted by the changes of a PR we must ignore any packages path that are not valid due to # not having their submodule or folder populated. # A packages path is ok to drop for this because if it isn't populated it is assumed outside # the repository and thus will not trigger the build. self.edk2_path_obj = path_utilities.Edk2Path( self.GetWorkspaceRoot(), self.GetPackagesPath(), error_on_invalid_pp=False) self.logger = logging.getLogger("edk2_pr_eval") actualPackagesDict = self.get_packages_to_build(self.requested_package_list) # # Report the packages that need to be built # self.logger.log(edk2_logging.SECTION, "Output Results") self.logger.critical("Need to Build:") if len(actualPackagesDict.keys()) > 0: max_pkg_width = max(len(t) for t in actualPackagesDict.keys()) for key, value in actualPackagesDict.items(): self.logger.critical(f"{key:{max_pkg_width}} Reason: {value}") else: self.logger.critical("None") # # If requested thru cmd line write to std out in defined format # This enabled CI pipelines # if self.output_csv_format_string is not None: pkgcsv = ",".join([x for x in actualPackagesDict.keys()]) print(self.output_csv_format_string.format(pkgcsv=pkgcsv)) if self.output_count_format_string is not None: pkgcount = len(actualPackagesDict.keys()) print(self.output_count_format_string.format(pkgcount=pkgcount)) return 0
def _ConfigEdk2PathUtil(self): ''' creates the path utility object based on the root path and package paths ''' self._Edk2PathUtil = path_utilities.Edk2Path(self.RootPath, self.PPs, error_on_invalid_pp=False)
def Parse(self): inPcdSection = False inLibSection = False inDepSection = False nextLineSection = False tokenspace = "" pathConverter = pu.Edk2Path(self.WorkspacePath, self.PackagePathList) i = 0 try: while i < len(self._RawContent): line = self._RawContent[i].strip() # parse start and end if line == ">----------------------------------------------------------------------------------------------------------------------<": # noqa: E501 nextLineSection = True elif line == "<---------------------------------------------------------------------------------------------------------------------->": # noqa: E501 inPcdSection = False inLibSection = False inDepSection = False nextLineSection = False # parse section header elif (nextLineSection): nextLineSection = False if (line == "Library"): inLibSection = True i += 1 # add additional line to skip the dashed line elif (line == "PCD"): inPcdSection = True i += 1 # add additional line to skip the dashed line elif (line == "Final Dependency Expression (DEPEX) Instructions"): inDepSection = True i += 1 # add additional line to skip the dashed line else: logging.debug("Unsupported Section: " + line) inPcdSection = False inLibSection = False inDepSection = False # Normal section parsing else: if (inLibSection): logging.debug("InLibSection: %s" % line) # get the whole statement library class statement templine = line.strip() while ('}' not in templine): i += 1 templine += self._RawContent[i].strip() # have good complete line with no whitespace/newline chars # first is the library instance INF # second is the library class lib_class = templine.partition('{')[2].partition( '}')[0].partition(':')[0].strip() lib_instance = templine.partition('{')[0].strip() # Take absolute path and convert to EDK build path RelativePath = pathConverter.GetEdk2RelativePathFromAbsolutePath( lib_instance) if (RelativePath is not None): self.Libraries[lib_class] = RelativePath else: self.Libraries[lib_class] = lib_instance i += 1 continue elif (inPcdSection): # this is the namespace token line if (len(line.split()) == 1): tokenspace = line # this is the main line of the PCD value elif (line.count("=") == 1 and line.count(":") == 1): while (line.count("\"") % 2) != 0: i += 1 line += " " + self._RawContent[i].rstrip() while (line.count('{') != line.count('}')): i += 1 line += " " + self._RawContent[i].rstrip() token = line.partition('=')[2] if (line.partition(':')[0].split() == []): token2 = "" else: token2 = line.partition(':')[0].split()[-1] self.PCDs[tokenspace + "." + token2] = token.strip() # this is the secondary lines of PCD values showing Defaults elif line.count(":") == 0 and line.count("=") == 1: while (line.count("\"") % 2) != 0: i += 1 line += self._RawContent[i].rstrip() elif (inDepSection): pass # not implemented right now else: # not in section...Must be header section line_partitioned = line.partition(':') if (line_partitioned[2] == ""): pass # not a name: value pair else: key = line_partitioned[0].strip().lower() value = line_partitioned[2].strip() if (key == "module name"): logging.debug("Parsing Mod: %s" % value) self.Name = value elif (key == "module inf path"): self.InfPath = value.replace("\\", "/") elif (key == "file guid"): self.Guid = value elif (key == "driver type"): value = value.strip() self.Type = value[value.index('(') + 1:-1] i += 1 except Exception: logging.debug("Exception in Parsing: %d" % i) raise
def RunTool(ws, PackagesPath, InputDir, OutputReport, BuildReportFile, IgnoreDirs, Name, Version, ParameterStringForDisplay): global Errors PathHelper = path_utilities.Edk2Path(ws, PackagesPath) ModuleDeps = [] # hold all deps ModuleList = [] AsBuiltMappings = [] LibraryClassInstanceDict = {} # # Iterate and find all INFs # for root, dirs, files in os.walk(InputDir): # remove all the ignore directories for a in [x for x in dirs if x.lower() in IgnoreDirs]: logging.debug("Ignoring directory %s" % a) dirs.remove(a) for name in files: if (name.lower().endswith('.inf')): fp = os.path.join(root, name) logging.debug("Processing File Path: %s" % fp) pkg = PathHelper.GetContainingPackage(fp).strip().lower() ip = inf_parser.InfParser() ip.SetBaseAbsPath(ws) ip.SetPackagePaths(PackagesPath) ip.ParseFile(fp) path = PathHelper.GetEdk2RelativePathFromAbsolutePath(fp) for prot in ip.ProtocolsUsed: # SrcPkg, SrcModule, Dep type, Dep Pkg, Dep, edk2path ) DepPkg = FindDepPackage(prot, ip) if(DepPkg is None): logging.critical( "Dep (%s) not found in packages." % prot) Errors.append( "Protocol Dep %s in INF %s not found in packages.," % (prot, fp)) continue logging.debug("Dep (%s) found in package %s" % (prot, DepPkg)) ModuleDeps.append({"SrcPkg": pkg, "SrcInf": name, "DepType": "Protocol", "DepPkg": DepPkg, "Dep": prot, "Edk2Path": path}) for g in ip.GuidsUsed: # SrcPkg, SrcModule, Dep type, Dep Pkg, Dep ) DepPkg = FindDepPackage(g, ip) if(DepPkg is None): logging.critical("Dep (%s) not found in packages." % g) Errors.append( "Guid Dep %s in INF %s not found in packages." % (g, fp)) continue logging.debug("Dep (%s) found in package %s" % (g, DepPkg)) ModuleDeps.append( {"SrcPkg": pkg, "SrcInf": name, "DepType": "Guid", "DepPkg": DepPkg, "Dep": g, "Edk2Path": path}) for ppi in ip.PpisUsed: # SrcPkg, SrcModule, Dep type, Dep Pkg, Dep ) DepPkg = FindDepPackage(ppi, ip) if(DepPkg is None): logging.critical( "Dep (%s) not found in packages." % ppi) Errors.append( "Ppi Dep %s in INF %s not found in packages." % (ppi, fp)) continue logging.debug("Dep (%s) found in package %s" % (ppi, DepPkg)) ModuleDeps.append({"SrcPkg": pkg, "SrcInf": name, "DepType": "Ppi", "DepPkg": DepPkg, "Dep": ppi, "Edk2Path": path}) for lc in ip.LibrariesUsed: # SrcPkg, SrcModule, Dep type, Dep Pkg, Dep ) DepPkg = FindDepPackage(lc, ip) if(DepPkg is None): logging.critical( "Dep (%s) not found in packages." % lc) Errors.append( "Library Class Dep %s in INF %s not found in packages." % (lc, fp)) continue logging.debug("Dep (%s) found in package %s" % (lc, DepPkg)) ModuleDeps.append({"SrcPkg": pkg, "SrcInf": name, "DepType": "Library", "DepPkg": DepPkg, "Dep": lc, "Edk2Path": path}) for pcd in ip.PcdsUsed: # SrcPkg, SrcModule, Dep type, Dep Pkg, Dep ) DepPkg = FindDepPackage(pcd, ip) if(DepPkg is None): logging.critical( "Dep (%s) not found in packages." % pcd) Errors.append( "Pcd Dep %s in INF %s not found in packages." % (pcd, fp)) continue logging.debug("Dep (%s) found in package %s" % (pcd, DepPkg)) ModuleDeps.append({"SrcPkg": pkg, "SrcInf": name, "DepType": "Pcd", "DepPkg": DepPkg, "Dep": pcd, "Edk2Path": path}) # Now add to module list ModObj = {} ModObj["Edk2Path"] = path ModObj["Pkg"] = pkg try: ModObj["Name"] = ip.Dict["BASE_NAME"] except Exception as e: Errors.append("INF has no BASE_NAME %s" % ip.Path) ModObj["Name"] = "NONE" ModObj["LibraryClass"] = "" ModObj["LibrarySupportedTypes"] = "" ModObj["SrcInf"] = name try: ModObj["Type"] = ip.Dict["MODULE_TYPE"] except Exception as e: Errors.append("INF has no MODULE_TYPE %s" % ip.Path) ModObj["Type"] = "NONE" if ip.LibraryClass != "": ModObj["LibraryClass"] = ip.LibraryClass ModObj["LibrarySupportedTypes"] = ip.SupportedPhases ModuleList.append(ModObj) # Process BuildReport if present if(BuildReportFile is not None) and (os.path.isfile(BuildReportFile)): ppcsv = "" for a in PackagesPath: ppcsv += "," + a br = buildreport_parser.BuildReport(BuildReportFile, ws, ppcsv, {}) br.BasicParse() for k in sorted(br.Modules): mod = br.Modules[k] AsBuildObj = {"ModuleInf": mod.InfPath, "ModuleName": mod.Name, "LibMappings": mod.Libraries} AsBuiltMappings.append(AsBuildObj) else: BuildReportFile = "" # Make string for parameters and make sure to escape and quote any argument with spaces p = '' for a in ParameterStringForDisplay[1:]: if(a.strip().count(' ') == 0): p += " " + a else: p += ' \"' + a + '\"' # Get the Pip Versions pip_versions = GetVersionOfPipDependencies() # # Convert into JSON # js = "{" + JS("ToolVersion", VERSION) js += JS("DateCollected", datetime.datetime.strftime( datetime.datetime.now(), "%A, %B %d, %Y %I:%M%p")) js += JS("CodebaseName", Name) js += JS("CodebaseVersion", Version) js += JS("ParserCmd", p) js += JS("Pytool_Library", pip_versions["edk2-pytool-library"]) js += "errors: " + json.dumps(list(set(Errors))) js += ", deps: " + json.dumps(ModuleDeps) js += ", ModList: " + json.dumps(ModuleList) js += ", AsBuiltMappings: " + json.dumps(AsBuiltMappings) js += ", " + JS("BuildReport", BuildReportFile, False) js += "}" # # Open template and replace placeholder with json # f = open(OutputReport, "w") template = open(os.path.join(sp, "Dep_template.html"), "r") for line in template.readlines(): if "%TO_BE_FILLED_IN_BY_PYTHON_SCRIPT%" in line: line = line.replace("%TO_BE_FILLED_IN_BY_PYTHON_SCRIPT%", js) f.write(line) template.close() f.close() return 0