예제 #1
0
    def guidlist_from_filesystem(
        folder: str, ignore_lines: list = list()) -> list:
        """ Create a list of GuidListEntry from files found in the file system

        folder: path string to root folder to walk
        ignore_lines: list of gitignore syntax to ignore files and folders
        """
        guids = []
        ignore = parse_gitignore_lines(ignore_lines,
                                       os.path.join(folder, "nofile.txt"),
                                       folder)
        for root, dirs, files in os.walk(folder):
            for d in dirs[:]:
                fullpath = os.path.join(root, d)
                if (ignore(fullpath)):
                    logging.debug(f"Ignore folder: {fullpath}")
                    dirs.remove(d)

            for name in files:
                fullpath = os.path.join(root, name)
                if (ignore(fullpath)):
                    logging.debug(f"Ignore file: {fullpath}")
                    continue

                new_guids = GuidList.parse_guids_from_edk2_file(fullpath)
                guids.extend(new_guids)
        return guids
예제 #2
0
    def _get_files_ignored_in_config(self):
        """"
        Returns a function that returns true if a given file string path is ignored in the plugin configuration file and false otherwise.
        """
        ignored_files = []
        if "IgnoreFiles" in self._package_config:
            ignored_files = self._package_config["IgnoreFiles"]

        # Pass "Package configuration file" as the source file path since
        # the actual configuration file name is unknown to this plugin and
        # this provides a generic description of the file that provided
        # the ignore file content.
        #
        # This information is only used for reporting (not used here) and
        # the ignore lines are being passed directly as they are given to
        # this plugin.
        return parse_gitignore_lines(ignored_files, "Package configuration file", self._abs_package_path)
예제 #3
0
    def RunBuildPlugin(self,
                       packagename,
                       Edk2pathObj,
                       pkgconfig,
                       environment,
                       PLM,
                       PLMHelper,
                       tc,
                       output_stream=None):
        Errors = []

        abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(
            packagename)

        if abs_pkg_path is None:
            tc.SetSkipped()
            tc.LogStdError("No package {0}".format(packagename))
            return -1

        # check for node
        return_buffer = StringIO()
        ret = RunCmd("node", "--version", outstream=return_buffer)
        if (ret != 0):
            tc.SetSkipped()
            tc.LogStdError("NodeJs not installed. Test can't run")
            logging.warning("NodeJs not installed. Test can't run")
            return -1
        node_version = return_buffer.getvalue().strip()  # format vXX.XX.XX
        tc.LogStdOut(f"Node version: {node_version}")
        version_aggregator.GetVersionAggregator().ReportVersion(
            "NodeJs", node_version, version_aggregator.VersionTypes.INFO)

        # Check for cspell
        return_buffer = StringIO()
        ret = RunCmd("cspell", "--version", outstream=return_buffer)
        if (ret != 0):
            tc.SetSkipped()
            tc.LogStdError("cspell not installed.  Test can't run")
            logging.warning("cspell not installed.  Test can't run")
            return -1
        cspell_version = return_buffer.getvalue().strip()  # format XX.XX.XX
        tc.LogStdOut(f"CSpell version: {cspell_version}")
        version_aggregator.GetVersionAggregator().ReportVersion(
            "CSpell", cspell_version, version_aggregator.VersionTypes.INFO)

        package_relative_paths_to_spell_check = SpellCheck.STANDARD_PLUGIN_DEFINED_PATHS

        #
        # Allow the ci.yaml to remove any of the above standard paths
        #
        if ("IgnoreStandardPaths" in pkgconfig):
            for a in pkgconfig["IgnoreStandardPaths"]:
                if (a in package_relative_paths_to_spell_check):
                    tc.LogStdOut(
                        f"ignoring standard path due to ci.yaml ignore: {a}")
                    package_relative_paths_to_spell_check.remove(a)
                else:
                    tc.LogStdOut(f"Invalid IgnoreStandardPaths value: {a}")

        #
        # check for any additional include paths defined by package config
        #
        if ("AdditionalIncludePaths" in pkgconfig):
            package_relative_paths_to_spell_check.extend(
                pkgconfig["AdditionalIncludePaths"])

        #
        # Make the path string for cspell to check
        #
        relpath = os.path.relpath(abs_pkg_path)
        cpsell_paths = " ".join([
            f"{relpath}/**/{x}" for x in package_relative_paths_to_spell_check
        ])

        # Make the config file
        config_file_path = os.path.join(Edk2pathObj.WorkspacePath, "Build",
                                        packagename,
                                        "cspell_actual_config.json")
        mydir = os.path.dirname(os.path.abspath(__file__))
        # load as yaml so it can have comments
        base = os.path.join(mydir, "cspell.base.yaml")
        with open(base, "r") as i:
            config = yaml.safe_load(i)

        if ("ExtendWords" in pkgconfig):
            config["words"].extend(pkgconfig["ExtendWords"])
        with open(config_file_path, "w") as o:
            json.dump(config, o)  # output as json so compat with cspell

        All_Ignores = []
        # Parse the config for other ignores
        if "IgnoreFiles" in pkgconfig:
            All_Ignores.extend(pkgconfig["IgnoreFiles"])

        # spell check all the files
        ignore = parse_gitignore_lines(
            All_Ignores, os.path.join(abs_pkg_path, "nofile.txt"),
            abs_pkg_path)

        # result is a list of strings like this
        #  C:\src\sp-edk2\edk2\FmpDevicePkg\FmpDevicePkg.dec:53:9 - Unknown word (Capule)
        EasyFix = []
        results = self._check_spelling(cpsell_paths, config_file_path)
        for r in results:
            path, _, word = r.partition(" - Unknown word ")
            if len(word) == 0:
                # didn't find pattern
                continue

            pathinfo = path.rsplit(":", 2)  # remove the line no info
            if (ignore(pathinfo[0])):  # check against ignore list
                tc.LogStdOut(f"ignoring error due to ci.yaml ignore: {r}")
                continue

            # real error
            EasyFix.append(word.strip().strip("()"))
            Errors.append(r)

        # Log all errors tc StdError
        for l in Errors:
            tc.LogStdError(l.strip())

        # Helper - Log the syntax needed to add these words to dictionary
        if len(EasyFix) > 0:
            EasyFix = sorted(set(a.lower() for a in EasyFix))
            tc.LogStdOut("\n Easy fix:")
            OneString = "If these are not errors add this to your ci.yaml file.\n"
            OneString += '"SpellCheck": {\n  "ExtendWords": ['
            for a in EasyFix:
                tc.LogStdOut(f'\n"{a}",')
                OneString += f'\n    "{a}",'
            logging.info(OneString.rstrip(",") + '\n  ]\n}')

        # add result to test case
        overall_status = len(Errors)
        if overall_status != 0:
            if "AuditOnly" in pkgconfig and pkgconfig["AuditOnly"]:
                # set as skipped if AuditOnly
                tc.SetSkipped()
                return -1
            else:
                tc.SetFailed(
                    "SpellCheck {0} Failed.  Errors {1}".format(
                        packagename, overall_status), "CHECK_FAILED")
        else:
            tc.SetSuccess()
        return overall_status