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
Ejemplo n.º 2
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
Ejemplo n.º 4
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)
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
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