.pytool/Plugin: Add CI plugins
https://bugzilla.tianocore.org/show_bug.cgi?id=2315 Add .pytool directory to the edk2 repository with the following plugins. These plugins are in a top level directory because that can be used with all packages and platforms. * CharEncodingCheck * CompilerPlugin * DependencyCheck * DscCompleteCheck * GuidCheck * LibraryClassCheck * SpellCheck Cc: Sean Brogan <sean.brogan@microsoft.com> Cc: Bret Barkelew <Bret.Barkelew@microsoft.com> Cc: Liming Gao <liming.gao@intel.com> Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
committed by
Michael D Kinney
parent
de4ce46d6e
commit
9da7846c88
118
.pytool/Plugin/CharEncodingCheck/CharEncodingCheck.py
Normal file
118
.pytool/Plugin/CharEncodingCheck/CharEncodingCheck.py
Normal file
@ -0,0 +1,118 @@
|
||||
# @file CharEncodingCheck.py
|
||||
#
|
||||
# Copyright (c) Microsoft Corporation.
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
##
|
||||
|
||||
|
||||
import os
|
||||
import logging
|
||||
from edk2toolext.environment.plugintypes.ci_build_plugin import ICiBuildPlugin
|
||||
from edk2toolext.environment.var_dict import VarDict
|
||||
|
||||
##
|
||||
# map
|
||||
##
|
||||
EcodingMap = {
|
||||
".md": 'utf-8',
|
||||
".dsc": 'utf-8',
|
||||
".dec": 'utf-8',
|
||||
".c": 'utf-8',
|
||||
".h": 'utf-8',
|
||||
".asm": 'utf-8',
|
||||
".masm": 'utf-8',
|
||||
".nasm": 'utf-8',
|
||||
".s": 'utf-8',
|
||||
".inf": 'utf-8',
|
||||
".asl": 'utf-8',
|
||||
".uni": 'utf-8',
|
||||
".py": 'utf-8'
|
||||
}
|
||||
|
||||
|
||||
class CharEncodingCheck(ICiBuildPlugin):
|
||||
"""
|
||||
A CiBuildPlugin that scans each file in the code tree and confirms the encoding is correct.
|
||||
|
||||
Configuration options:
|
||||
"CharEncodingCheck": {
|
||||
"IgnoreFiles": []
|
||||
}
|
||||
"""
|
||||
|
||||
def GetTestName(self, packagename: str, environment: VarDict) -> tuple:
|
||||
""" Provide the testcase name and classname for use in reporting
|
||||
testclassname: a descriptive string for the testcase can include whitespace
|
||||
classname: should be patterned <packagename>.<plugin>.<optionally any unique condition>
|
||||
|
||||
Args:
|
||||
packagename: string containing name of package to build
|
||||
environment: The VarDict for the test to run in
|
||||
Returns:
|
||||
a tuple containing the testcase name and the classname
|
||||
(testcasename, classname)
|
||||
"""
|
||||
return ("Check for valid file encoding for " + packagename, packagename + ".CharEncodingCheck")
|
||||
|
||||
##
|
||||
# External function of plugin. This function is used to perform the task of the ci_build_plugin Plugin
|
||||
#
|
||||
# - package is the edk2 path to package. This means workspace/packagepath relative.
|
||||
# - edk2path object configured with workspace and packages path
|
||||
# - PkgConfig Object (dict) for the pkg
|
||||
# - EnvConfig Object
|
||||
# - Plugin Manager Instance
|
||||
# - Plugin Helper Obj Instance
|
||||
# - Junit Logger
|
||||
# - output_stream the StringIO output stream from this plugin via logging
|
||||
def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM, PLMHelper, tc, output_stream=None):
|
||||
overall_status = 0
|
||||
files_tested = 0
|
||||
|
||||
abs_pkg_path = Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(packagename)
|
||||
|
||||
if abs_pkg_path is None:
|
||||
tc.SetSkipped()
|
||||
tc.LogStdError("No Package folder {0}".format(abs_pkg_path))
|
||||
return 0
|
||||
|
||||
for (ext, enc) in EcodingMap.items():
|
||||
files = self.WalkDirectoryForExtension([ext], abs_pkg_path)
|
||||
files = [Edk2pathObj.GetEdk2RelativePathFromAbsolutePath(x) for x in files] # make edk2relative path so can process ignores
|
||||
|
||||
if "IgnoreFiles" in pkgconfig:
|
||||
for a in pkgconfig["IgnoreFiles"]:
|
||||
a = a.replace(os.sep, "/")
|
||||
try:
|
||||
tc.LogStdOut("Ignoring File {0}".format(a))
|
||||
files.remove(a)
|
||||
except:
|
||||
tc.LogStdError("CharEncodingCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
|
||||
logging.info("CharEncodingCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore file".format(a))
|
||||
|
||||
files = [Edk2pathObj.GetAbsolutePathOnThisSytemFromEdk2RelativePath(x) for x in files]
|
||||
for a in files:
|
||||
files_tested += 1
|
||||
if(self.TestEncodingOk(a, enc)):
|
||||
logging.debug("File {0} Passed Encoding Check {1}".format(a, enc))
|
||||
else:
|
||||
tc.LogStdError("Encoding Failure in {0}. Not {1}".format(a, enc))
|
||||
overall_status += 1
|
||||
|
||||
tc.LogStdOut("Tested Encoding on {0} files".format(files_tested))
|
||||
if overall_status is not 0:
|
||||
tc.SetFailed("CharEncoding {0} Failed. Errors {1}".format(packagename, overall_status), "CHAR_ENCODING_CHECK_FAILED")
|
||||
else:
|
||||
tc.SetSuccess()
|
||||
return overall_status
|
||||
|
||||
def TestEncodingOk(self, apath, encodingValue):
|
||||
try:
|
||||
with open(apath, "rb") as fobj:
|
||||
fobj.read().decode(encodingValue)
|
||||
except Exception as exp:
|
||||
logging.error("Encoding failure: file: {0} type: {1}".format(apath, encodingValue))
|
||||
logging.debug("EXCEPTION: while processing {1} - {0}".format(exp, apath))
|
||||
return False
|
||||
|
||||
return True
|
Reference in New Issue
Block a user