def test_dircmp_diff_files_accuracy(self):
"""Different files are identified as such using filecmp.dircmp()"""
file1 = os.path.join(self.folder1, 'hello_world.txt')
with open(file1, 'w') as file:
file.write('foo')
file2 = os.path.join(self.folder2, 'hello_world.txt')
with open(file2, 'w') as file:
file.write('bar')
comparison = filecmp.dircmp(self.folder1, self.folder2)
self.assertTrue(comparison.diff_files == ['hello_world.txt'])
self.assertTrue(comparison.same_files == [])
python类dircmp()的实例源码
def is_same(dir1, dir2, **kwargs):
"""
Compare two directory trees content.
Return False if they differ, True is they are the same.
"""
compared = dircmp(dir1, dir2, **kwargs)
if (compared.left_only or compared.right_only or compared.diff_files
or compared.funny_files):
return False
for subdir in compared.common_dirs:
if not is_same(os.path.join(dir1, subdir), os.path.join(dir2, subdir), **kwargs):
return False
return True
def is_same2(dir1, dir2, raise_exc=True, **kwargs):
"""
Compare two directory trees content. Only compare files in both directories.
Return False if they differ, True is they are the same.
"""
cmp = filecmp.dircmp(dir1, dir2, **kwargs)
return _dir_cmp(cmp, raise_exc)
def test_report_partial_closure(self):
left_dir, right_dir = self.dir, self.dir_same
d = filecmp.dircmp(left_dir, right_dir)
expected_report = [
"diff {} {}".format(self.dir, self.dir_same),
"Identical files : ['file']",
]
self._assert_report(d.report_partial_closure, expected_report)
def test_report_full_closure(self):
left_dir, right_dir = self.dir, self.dir_same
d = filecmp.dircmp(left_dir, right_dir)
expected_report = [
"diff {} {}".format(self.dir, self.dir_same),
"Identical files : ['file']",
]
self._assert_report(d.report_full_closure, expected_report)
def test_destination_exists(self):
self.dest_tree = {
"file1": "stuff",
"file2": "stuff",
"dir1": {
"file3": "stuff"
}
}
create_files_from_tree(self.dest_tree, parent=self.dest_dir)
self.link_and_print()
dircmp(self.source_dir, self.dest_dir)
result = dircmp(self.source_dir, self.dest_dir)
self.recursive_dircmp(result)
def test_source_exists(self):
self.source_tree = {
"file1": "stuff",
"file2": "stuff",
"dir1": {
"file3": "stuff"
}
}
create_files_from_tree(self.source_tree, parent=self.source_dir)
self.link_and_print()
dircmp(self.source_dir, self.dest_dir)
result = dircmp(self.source_dir, self.dest_dir)
self.recursive_dircmp(result)
def assertEqualPaths(self, x, y):
dircmp = filecmp.dircmp(x, y)
self.assertEmpty(dircmp.left_only)
self.assertEmpty(dircmp.right_only)
self.assertEmpty(dircmp.diff_files)
#
# def tearDown(self):
# for path in self.temp_data:
# if os.path.isdir(path):
# shutil.rmtree(path)
# elif os.path.exists(path):
# os.remove(path)
def _diff(self, baselinedir, outputdir, dc=None):
if dc is None:
dc = filecmp.dircmp(baselinedir,
outputdir,
['.svn'])
if dc.left_only:
self.fail("Files or subdirectories missing from output: "
+str(dc.left_only))
if dc.right_only:
self.fail("Files or subdirectories missing from baseline: "
+str(dc.right_only))
for name in dc.diff_files:
fromfile = join(dc.left, name)
tofile = join(dc.right, name)
with open(fromfile, 'r') as f_from:
fromlines = f_from.readlines()
with open(tofile, 'r') as f_to:
tolines = f_to.readlines()
diff = difflib.context_diff(fromlines, tolines,
fromfile+" (baseline)",
tofile+" (output)")
diff = list(diff)
# The filecmp.dircmp function does a weaker
# comparison that can sometimes lead to false
# positives. Make sure the true diff is not empty
# before we call this a failure.
if len(diff) > 0:
out = StringIO()
out.write("Output file does not match baseline:\n")
for line in diff:
out.write(line)
self.fail(out.getvalue())
for subdir in dc.subdirs:
self._diff(join(baselinedir, subdir),
join(outputdir, subdir),
dc=dc.subdirs[subdir])
shutil.rmtree(outputdir, ignore_errors=True)
file_cmp_class.py 文件源码
项目:Automation-Framework-for-devices
作者: tok-gogogo
项目源码
文件源码
阅读 19
收藏 0
点赞 0
评论 0
def path_cmp(self,PATH1,PATH2):
self.File1 = PATH1
self.File2 = PATH2
if self.path_exist(self.File1)==False:
return False
if self.path_exist(self.File2)==False:
return False
#filecmp.dircmp(self.File1,self.File2)
result = self.stdout_file(self.File1,self.File2)
return result
def analyze(dcres, wpPath):
"""Get extra, changed and missing files from a dircmp results object.
From dircmp results find:
1. Any files that differ.
2. Extra files in left that are not in right.
3. Missing files that are in right but not in left.
Recursively enter sub directories to continue search.
When searching for extra files, certain files and directories that are
user modifiable should be ignored. For example, 'wp-content/themes' will
likely contain unique files that will not appear in a new copy of the
same WordPress version. These should be ignored to avoid giving false
positives.
"""
diff = set()
extra = set()
missing = set()
# 1. Get modified files
[diff.add(os.path.join(dcres.left, f)) for f in dcres.diff_files]
# 2. Get extra files
for name in dcres.left_only:
path = os.path.join(dcres.left, name)
if not ignored_file(path, wpPath): # ignore user modified
if not os.path.isdir(path): # do not add directories
extra.add(path)
# 3. Get missing files
[missing.add(os.path.join(dcres.right, f)) for f in dcres.right_only]
# Recurse into each sub dir
for sub_dcres in dcres.subdirs.values():
newDiff, newExtra, newMissing = analyze(sub_dcres, wpPath)
diff = diff.union(newDiff)
extra = extra.union(newExtra)
missing = missing.union(newMissing)
return diff, extra, missing
def reorder(miz_file_path, target_dir, skip_options_file):
LOGGER.debug('re-ordering miz file: {}'.format(miz_file_path))
LOGGER.debug('destination folder: {}'.format(target_dir))
LOGGER.debug('{}option file'.format('skipping' if skip_options_file else 'including'))
if not Path(target_dir).exists():
LOGGER.debug(f'creating directory {target_dir}')
Path(target_dir).makedirs()
with Miz(miz_file_path, overwrite=True) as m:
def mirror_dir(src, dst):
LOGGER.debug('{} -> {}'.format(src, dst))
diff_ = dircmp(src, dst, ignore)
diff_list = diff_.left_only + diff_.diff_files
LOGGER.debug('differences: {}'.format(diff_list))
for x in diff_list:
source = Path(diff_.left).joinpath(x)
target = Path(diff_.right).joinpath(x)
LOGGER.debug('looking at: {}'.format(x))
if source.isdir():
LOGGER.debug('isdir: {}'.format(x))
if not target.exists():
LOGGER.debug('creating: {}'.format(x))
target.mkdir()
mirror_dir(source, target)
else:
LOGGER.debug('copying: {}'.format(x))
source.copy2(diff_.right)
for sub in diff_.subdirs.values():
assert isinstance(sub, dircmp)
mirror_dir(sub.left, sub.right)
m._encode()
if skip_options_file:
ignore = ['options']
else:
ignore = []
mirror_dir(m.tmpdir, target_dir)
def check_addon_alteration(self, addon, dir_path, temp_directory):
addon_url = "{}{}.{}.zip".format(self.download_addon_url, addon["name"], addon["version"])
if addon["version"] == "trunk":
addon_url = "{}{}.zip".format(self.download_addon_url, addon["name"])
log.print_cms("default", "To download the addon: " + addon_url, "", 1)
try:
response = requests.get(addon_url)
response.raise_for_status()
if response.status_code == 200:
zip_file = zipfile.ZipFile(io.BytesIO(response.content), 'r')
zip_file.extractall(temp_directory)
zip_file.close()
project_dir = os.path.join(dir_path, self.wp_content, "plugins", addon["name"])
project_dir_hash = dirhash(project_dir, 'sha1')
ref_dir = os.path.join(temp_directory, addon["name"])
ref_dir_hash = dirhash(ref_dir, 'sha1')
if project_dir_hash == ref_dir_hash:
altered = "NO"
log.print_cms("good", "Different from sources : " + altered, "", 1)
else:
altered = "YES"
log.print_cms("alert", "Different from sources : " + altered, "", 1)
ignored = ["css", "img", "js", "fonts", "images"]
dcmp = dircmp(project_dir, ref_dir, ignored)
uCMS.diff_files(dcmp, addon["alterations"], project_dir)
addon["edited"] = altered
if addon["alterations"] is not None:
msg = "[+] For further analysis, archive downloaded here : " + ref_dir
log.print_cms("info", msg, "", 1)
except requests.exceptions.HTTPError as e:
msg = "The download link is not standard. Search manually !"
log.print_cms("alert", msg, "", 1)
addon["notes"] = msg
return msg, e
return altered, None
def check_addon_alteration(self, addon, addon_path, temp_directory):
addon_url = "{}{}-{}.zip".format(self.download_addon_url, addon["name"], addon["version"])
if addon["version"] == "VERSION":
# TODO
return None, None
log.print_cms("default", "To download the addon : " + addon_url, "", 1)
altered = ""
try:
response = requests.get(addon_url)
response.raise_for_status()
if response.status_code == 200:
zip_file = zipfile.ZipFile(io.BytesIO(response.content), 'r')
zip_file.extractall(temp_directory)
zip_file.close()
project_dir_hash = dirhash(addon_path, 'sha1')
ref_dir = os.path.join(temp_directory, addon["name"])
ref_dir_hash = dirhash(ref_dir, 'sha1')
if project_dir_hash == ref_dir_hash:
altered = "NO"
log.print_cms("good", "Different from sources : " + altered, "", 1)
else:
altered = "YES"
log.print_cms("alert", "Different from sources : " + altered, "", 1)
ignored = ["tests"]
dcmp = dircmp(addon_path, ref_dir, ignored)
uCMS.diff_files(dcmp, addon["alterations"], addon_path)
addon["edited"] = altered
except requests.exceptions.HTTPError as e:
msg = "The download link is not standard. Search manually !"
log.print_cms("alert", msg, "", 1)
addon["notes"] = msg
return msg, e
return altered, None
def _finddifference(self, casedirpath):
# Get the full output and reference paths
outpath = os.path.join(casedirpath, "out")
refpath = os.path.join(casedirpath, "ref")
# Check for the presence of the reference directory
if not os.path.isdir(refpath): return "Test case has no reference directory"
# Initialize lists to contain the extra files, missing files and differing files
extra = []
missing = []
differ = []
# Verify list of filenames
if len(filter(lambda fn: os.path.isdir(fn), os.listdir(outpath))) > 0: return "Output contains a directory"
dircomp = filecmp.dircmp(outpath, refpath, ignore=['.DS_Store'])
# Create a list of files that were not present in the reference directory
for file in dircomp.left_only: extra.append(file)
# Create a list of files that are missing from the output directory
for file in dircomp.right_only: missing.append(file)
# Compare files, focusing on those that aren't trivially equal.
matches, mismatches, errors = filecmp.cmpfiles(outpath, refpath, dircomp.common, shallow=False)
for filename in mismatches + errors:
reffile = os.path.join(refpath, filename)
outfile = os.path.join(outpath, filename)
# For a soft comparison between files, check if both files are similar enough
if self._parallel:
if not similarfiles(reffile, outfile): differ.append(filename)
# In the other case, check if both files are equal (except for potential timestamps)
else:
if not equalfiles(reffile, outfile): differ.append(filename)
# Return the list of extra files, the list of missing files and the list of differing files
return extra, missing, differ
# -----------------------------------------------------------------
# This functions searches for directories within a certain parent directories that have a specific name
def _finddifference(self, casedirpath):
# Get the full output and reference paths
outpath = os.path.join(casedirpath, "out")
refpath = os.path.join(casedirpath, "ref")
# Check for the presence of the reference directory
if not os.path.isdir(refpath): return "Test case has no reference directory"
# Initialize lists to contain the extra files, missing files and differing files
extra = []
missing = []
differ = []
# Verify list of filenames
if len(filter(lambda fn: os.path.isdir(fn), os.listdir(outpath))) > 0: return "Output contains a directory"
dircomp = filecmp.dircmp(outpath, refpath, ignore=['.DS_Store'])
# Create a list of files that were not present in the reference directory
for file in dircomp.left_only: extra.append(file)
# Create a list of files that are missing from the output directory
for file in dircomp.right_only: missing.append(file)
# Compare files, focusing on those that aren't trivially equal.
matches, mismatches, errors = filecmp.cmpfiles(outpath, refpath, dircomp.common, shallow=False)
for filename in mismatches + errors:
reffile = os.path.join(refpath, filename)
outfile = os.path.join(outpath, filename)
# For a soft comparison between files, check if both files are similar enough
if self._parallel:
if not similarfiles(reffile, outfile): differ.append(filename)
# In the other case, check if both files are equal (except for potential timestamps)
else:
if not equalfiles(reffile, outfile): differ.append(filename)
# Return the list of extra files, the list of missing files and the list of differing files
return extra, missing, differ
# -----------------------------------------------------------------
# This functions searches for directories within a certain parent directories that have a specific name
def _recursive_dircmp(folder1, folder2, prefix='.'):
"""Return a recursive dircmp comparison report as a dictionary."""
comparison = filecmp.dircmp(folder1, folder2)
data = {
'left': [r'{}/{}'.format(prefix, i) for i in comparison.left_only],
'right': [r'{}/{}'.format(prefix, i) for i in comparison.right_only],
'both': [r'{}/{}'.format(prefix, i) for i in comparison.common_files],
}
for datalist in data.values():
datalist.sort()
if comparison.common_dirs:
for folder in comparison.common_dirs:
# Update prefix to include new sub_folder
prefix += '/' + folder
# Compare common folder and add results to the report
sub_folder1 = os.path.join(folder1, folder)
sub_folder2 = os.path.join(folder2, folder)
sub_report = _recursive_dircmp(sub_folder1, sub_folder2, prefix)
# Add results from sub_report to main report
for key, value in sub_report.items():
data[key] += value
return data
def main():
parser = create_args()
args = parser.parse_args()
global verbose
verbose = args.verbose
msg("""
___ _ _ _
/ __|_) | | |
_ _ _ ____ | |__ _| | ____ ____ ____ ____| |_ _ ___ ____ ____
| | | | _ \ | __) | |/ _ ) / _ | _ \ / _ | | | | |/___)/ _ )/ ___)
| | | | | | | | | | | ( (/ / ( ( | | | | ( ( | | | |_| |___ ( (/ /| |
\____| ||_/ |_| |_|_|\____) \_||_|_| |_|\_||_|_|\__ (___/ \____)_|
|_| (____/
""")
msg('Setting up:')
wpPath, otherWpPath = process_wp_dirs(args)
if (wpPath is False) or (otherWpPath is False):
msg('ERROR: could not get WordPress directories for comparison', True)
sys.exit()
# Get plugins and themes, but only when a new WordPress directory has
# been created.
if not args.other_wordpress_path:
msg('Getting plugins:')
plugins = find_plugins(wpPath)
for plugin in plugins:
name = plugin['name']
version = plugin['version']
res = get_plugin(name, version, otherWpPath)
if not res:
msg("ERROR: Could not download %s %s" % (name, version), True)
msg('Getting themes:')
themes = find_themes(wpPath)
for theme in themes:
name = theme['name']
version = theme['version']
res = get_theme(name, version, otherWpPath)
if not res:
msg("ERROR: Could not download %s %s" % (name, version), True)
msg('Comparing %s with %s' % (wpPath, otherWpPath))
msg('Starting Analysis:')
dcres = dircmp(wpPath, otherWpPath)
diff, extra, missing = analyze(dcres, wpPath)
uploadsPath = os.path.join(wpPath, 'wp-content', 'uploads')
phpFiles = search_dir_for_exts(uploadsPath, PHP_FILE_EXTENSIONS)
print_analysis(diff, extra, missing, phpFiles)
if args.remove_temporary_files:
if os.path.exists(TEMP_DIR):
msg("Removing %s " % TEMP_DIR)
shutil.rmtree(TEMP_DIR)