Skip to content

Commit

Permalink
.pytool/Plugin/EccCheck: Remove RevertCode()
Browse files Browse the repository at this point in the history
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2986

The RevertCode() method uses git reset which can remove
local changes. Instead of modifying the local files, a
copy of the package passed into the EccCheck tool is
copied to a temp directory in Build/ecctemp.  This same
temp directory is also used for exception.xml. The working
directory used by ECC is also set to this same temp
directory. The combination of these changes eliminates
operations that that modified the git state.

Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Michael Kubacki <michael.kubacki@microsoft.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Acked-by: Sean Brogan <sean.brogan@microsoft.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
  • Loading branch information
mdkinney authored and mergify[bot] committed Nov 29, 2021
1 parent ef9a059 commit 6987761
Showing 1 changed file with 53 additions and 40 deletions.
93 changes: 53 additions & 40 deletions .pytool/Plugin/EccCheck/EccCheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,32 +69,50 @@ def RunBuildPlugin(self, packagename, Edk2pathObj, pkgconfig, environment, PLM,
env.set_shell_var('WORKSPACE', workspace_path)
env.set_shell_var('PACKAGES_PATH', os.pathsep.join(Edk2pathObj.PackagePathList))
self.ECC_PASS = True
self.ApplyConfig(pkgconfig, workspace_path, basetools_path, packagename)

# Create temp directory
temp_path = os.path.join(workspace_path, 'Build', '.pytool', 'Plugin', 'EccCheck')
# Delete temp directory
if os.path.exists(temp_path):
shutil.rmtree(temp_path)
# Copy package being scanned to temp_path
shutil.copytree (
os.path.join(workspace_path, packagename),
os.path.join(temp_path, packagename),
symlinks=True
)
# Copy exception.xml to temp_path
shutil.copyfile (
os.path.join(basetools_path, "Source", "Python", "Ecc", "exception.xml"),
os.path.join(temp_path, "exception.xml")
)

self.ApplyConfig(pkgconfig, temp_path, packagename)
modify_dir_list = self.GetModifyDir(packagename)
patch = self.GetDiff(packagename)
ecc_diff_range = self.GetDiffRange(patch, packagename, workspace_path)
self.GenerateEccReport(modify_dir_list, ecc_diff_range, workspace_path, basetools_path)
ecc_log = os.path.join(workspace_path, "Ecc.log")
self.RevertCode()
ecc_diff_range = self.GetDiffRange(patch, packagename, temp_path)
#
# Use temp_path as working directory when running ECC tool
#
self.GenerateEccReport(modify_dir_list, ecc_diff_range, temp_path, basetools_path)
ecc_log = os.path.join(temp_path, "Ecc.log")
if self.ECC_PASS:
# Delete temp directory
if os.path.exists(temp_path):
shutil.rmtree(temp_path)
tc.SetSuccess()
self.RemoveFile(ecc_log)
return 0
else:
with open(ecc_log, encoding='utf8') as output:
ecc_output = output.readlines()
for line in ecc_output:
logging.error(line.strip())
self.RemoveFile(ecc_log)
tc.SetFailed("EccCheck failed for {0}".format(packagename), "Ecc detected issues")
# Delete temp directory
if os.path.exists(temp_path):
shutil.rmtree(temp_path)
tc.SetFailed("EccCheck failed for {0}".format(packagename), "CHECK FAILED")
return 1

def RevertCode(self) -> None:
submoudle_params = "submodule update --init"
RunCmd("git", submoudle_params)
reset_params = "reset HEAD --hard"
RunCmd("git", reset_params)

def GetDiff(self, pkg: str) -> List[str]:
return_buffer = StringIO()
params = "diff --unified=0 origin/master HEAD"
Expand All @@ -105,11 +123,6 @@ def GetDiff(self, pkg: str) -> List[str]:

return patch

def RemoveFile(self, file: str) -> None:
if os.path.exists(file):
os.remove(file)
return

def GetModifyDir(self, pkg: str) -> List[str]:
return_buffer = StringIO()
params = "diff --name-status" + ' HEAD' + ' origin/master'
Expand All @@ -132,14 +145,14 @@ def GetModifyDir(self, pkg: str) -> List[str]:
modify_dir_list = list(set(modify_dir_list))
return modify_dir_list

def GetDiffRange(self, patch_diff: List[str], pkg: str, workingdir: str) -> Dict[str, List[Tuple[int, int]]]:
def GetDiffRange(self, patch_diff: List[str], pkg: str, temp_path: str) -> Dict[str, List[Tuple[int, int]]]:
IsDelete = True
StartCheck = False
range_directory: Dict[str, List[Tuple[int, int]]] = {}
for line in patch_diff:
modify_file = self.FindModifyFile.findall(line)
if modify_file and pkg in modify_file[0] and not StartCheck and os.path.isfile(modify_file[0]):
modify_file_comment_dic = self.GetCommentRange(modify_file[0], workingdir)
modify_file_comment_dic = self.GetCommentRange(modify_file[0], temp_path)
IsDelete = False
StartCheck = True
modify_file_dic = modify_file[0]
Expand All @@ -158,11 +171,13 @@ def GetDiffRange(self, patch_diff: List[str], pkg: str, workingdir: str) -> Dict
range_directory[modify_file_dic].append(i)
return range_directory

def GetCommentRange(self, modify_file: str, workingdir: str) -> List[Tuple[int, int]]:
modify_file_path = os.path.join(workingdir, modify_file)
def GetCommentRange(self, modify_file: str, temp_path: str) -> List[Tuple[int, int]]:
comment_range: List[Tuple[int, int]] = []
modify_file_path = os.path.join(temp_path, modify_file)
if not os.path.exists (modify_file_path):
return comment_range
with open(modify_file_path) as f:
line_no = 1
comment_range: List[Tuple[int, int]] = []
Start = False
for line in f:
if line.startswith('/**'):
Expand All @@ -179,35 +194,33 @@ def GetCommentRange(self, modify_file: str, workingdir: str) -> List[Tuple[int,
return comment_range

def GenerateEccReport(self, modify_dir_list: List[str], ecc_diff_range: Dict[str, List[Tuple[int, int]]],
workspace_path: str, basetools_path: str) -> None:
temp_path: str, basetools_path: str) -> None:
ecc_need = False
ecc_run = True
config = os.path.join(basetools_path, "Source", "Python", "Ecc", "config.ini")
exception = os.path.join(basetools_path, "Source", "Python", "Ecc", "exception.xml")
report = os.path.join(workspace_path, "Ecc.csv")
config = os.path.normpath(os.path.join(basetools_path, "Source", "Python", "Ecc", "config.ini"))
exception = os.path.normpath(os.path.join(temp_path, "exception.xml"))
report = os.path.normpath(os.path.join(temp_path, "Ecc.csv"))
for modify_dir in modify_dir_list:
target = os.path.join(workspace_path, modify_dir)
target = os.path.normpath(os.path.join(temp_path, modify_dir))
logging.info('Run ECC tool for the commit in %s' % modify_dir)
ecc_need = True
ecc_params = "-c {0} -e {1} -t {2} -r {3}".format(config, exception, target, report)
return_code = RunCmd("Ecc", ecc_params, workingdir=workspace_path)
return_code = RunCmd("Ecc", ecc_params, workingdir=temp_path)
if return_code != 0:
ecc_run = False
break
if not ecc_run:
logging.error('Fail to run ECC tool')
self.ParseEccReport(ecc_diff_range, workspace_path)
self.ParseEccReport(ecc_diff_range, temp_path)

if not ecc_need:
logging.info("Doesn't need run ECC check")

revert_params = "checkout -- {}".format(exception)
RunCmd("git", revert_params)
return

def ParseEccReport(self, ecc_diff_range: Dict[str, List[Tuple[int, int]]], workspace_path: str) -> None:
ecc_log = os.path.join(workspace_path, "Ecc.log")
ecc_csv = os.path.join(workspace_path, "Ecc.csv")
def ParseEccReport(self, ecc_diff_range: Dict[str, List[Tuple[int, int]]], temp_path: str) -> None:
ecc_log = os.path.join(temp_path, "Ecc.log")
ecc_csv = os.path.join(temp_path, "Ecc.csv")
row_lines = []
ignore_error_code = self.GetIgnoreErrorCode()
if os.path.exists(ecc_csv):
Expand Down Expand Up @@ -236,24 +249,24 @@ def ParseEccReport(self, ecc_diff_range: Dict[str, List[Tuple[int, int]]], works
log.writelines(all_line)
return

def ApplyConfig(self, pkgconfig: Dict[str, List[str]], workspace_path: str, basetools_path: str, pkg: str) -> None:
def ApplyConfig(self, pkgconfig: Dict[str, List[str]], temp_path: str, pkg: str) -> None:
if "IgnoreFiles" in pkgconfig:
for a in pkgconfig["IgnoreFiles"]:
a = os.path.join(workspace_path, pkg, a)
a = os.path.join(temp_path, pkg, a)
a = a.replace(os.sep, "/")

logging.info("Ignoring Files {0}".format(a))
if os.path.exists(a):
if os.path.isfile(a):
self.RemoveFile(a)
os.remove(a)
elif os.path.isdir(a):
shutil.rmtree(a)
else:
logging.error("EccCheck.IgnoreInf -> {0} not found in filesystem. Invalid ignore files".format(a))

if "ExceptionList" in pkgconfig:
exception_list = pkgconfig["ExceptionList"]
exception_xml = os.path.join(basetools_path, "Source", "Python", "Ecc", "exception.xml")
exception_xml = os.path.join(temp_path, "exception.xml")
try:
logging.info("Appending exceptions")
self.AppendException(exception_list, exception_xml)
Expand Down

0 comments on commit 6987761

Please sign in to comment.