Commit e47c4bf8 authored by Chris Lamb's avatar Chris Lamb 💬

Add a --exclude-directory-metadata=recursive option to support ignoring...

Add a --exclude-directory-metadata=recursive option to support ignoring timestamp (etc.) differences in containers. (Closes: #907600, #36)
parent 12e25406
Pipeline #36959 passed with stage
in 15 minutes and 14 seconds
......@@ -137,7 +137,7 @@ def xattr(path1, path2):
def compare_meta(path1, path2):
if Config().exclude_directory_metadata:
if Config().exclude_directory_metadata in ('yes', 'recursive'):
logger.debug(
"Excluding directory metadata for paths (%s, %s)", path1, path2)
return []
......
......@@ -67,7 +67,7 @@ def compare_root_paths(path1, path2):
file2 = specialize(FilesystemFile(path2, container=container2))
difference = compare_files(file1, file2)
if not Config().exclude_directory_metadata:
if Config().exclude_directory_metadata in ('no', 'recursive'):
meta = compare_meta(path1, path2)
if meta:
# Create an "empty" difference so we have something to attach file
......
......@@ -26,6 +26,7 @@ import libarchive
import collections
from diffoscope.exc import ContainerExtractionError
from diffoscope.config import Config
from diffoscope.excludes import any_excluded
from diffoscope.tempfiles import get_temporary_directory
......@@ -99,6 +100,13 @@ def list_libarchive(path, ignore_errors=False):
try:
with libarchive.file_reader(path) as archive:
for entry in archive:
name_and_link = entry.name
if entry.issym:
name_and_link = '{entry.name} -> {entry.linkname}'.format(
entry=entry)
if Config().exclude_directory_metadata == 'recursive':
yield '{name_and_link}\n'.format(name_and_link=name_and_link)
continue
if entry.isblk or entry.ischr:
size_or_dev = '{major:>3},{minor:>3}'.format(
major=entry.rdevmajor, minor=entry.rdevminor)
......@@ -106,11 +114,6 @@ def list_libarchive(path, ignore_errors=False):
size_or_dev = entry.size
mtime = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(entry.mtime)
) + '.{:06d}'.format(entry.mtime_nsec // 1000)
if entry.issym:
name_and_link = '{entry.name} -> {entry.linkname}'.format(
entry=entry)
else:
name_and_link = entry.name
if entry.uname:
user = '{user:<8} {uid:>7}'.format(user=entry.uname.decode(
'utf-8', errors='surrogateescape'), uid='({})'.format(entry.uid))
......
......@@ -23,6 +23,7 @@ import shutil
import os.path
import zipfile
from diffoscope.config import Config
from diffoscope.tools import tool_required
from diffoscope.difference import Difference
from diffoscope.exc import ContainerExtractionError
......@@ -163,9 +164,11 @@ class ZipFile(File):
def compare_details(self, other, source=None):
differences = []
zipinfo_difference = Difference.from_command(Zipinfo, self.path, other.path) or \
Difference.from_command(ZipinfoVerbose, self.path, other.path) or \
Difference.from_command(BsdtarVerbose, self.path, other.path)
zipinfo_difference = None
if Config().exclude_directory_metadata != 'recursive':
zipinfo_difference = Difference.from_command(Zipinfo, self.path, other.path) or \
Difference.from_command(ZipinfoVerbose, self.path, other.path) or \
Difference.from_command(BsdtarVerbose, self.path, other.path)
zipnote_difference = Difference.from_command(Zipnote, self.path, other.path)
for x in (zipinfo_difference, zipnote_difference):
if x is not None:
......@@ -218,6 +221,8 @@ class MozillaZipFile(File):
return file.file_header[4:8] == b'PK\x01\x02'
def compare_details(self, other, source=None):
if Config().exclude_directory_metadata == 'recursive':
return []
zipinfo_difference = Difference.from_command(MozillaZipinfo, self.path, other.path) or \
Difference.from_command(MozillaZipinfoVerbose, self.path, other.path) or \
Difference.from_command(BsdtarVerbose, self.path, other.path)
......
......@@ -60,7 +60,7 @@ class Config(object):
self.enforce_constraints = True
self.excludes = ()
self.exclude_commands = ()
self.exclude_directory_metadata = False
self.exclude_directory_metadata = 'no'
self.compute_visual_diffs = False
self.max_container_depth = 50
self.use_dbgsym = False
......
......@@ -189,14 +189,15 @@ def create_parser():
'differences caused by something represented '
'elsewhere. Use this option to disable commands that '
'use a lot of resources.')
group3.add_argument('--exclude-directory-metadata', '--no-exclude-directory-metadata',
action=BooleanAction, default=None,
group3.add_argument('--exclude-directory-metadata',
choices=('auto', 'yes', 'no', 'recursive'),
help='Exclude directory metadata. Useful if comparing '
'files whose filesystem-level metadata is not intended '
'to be distributed to other systems. This is true for '
'most distributions package builders, but not true '
'for the output of commands such as `make install`. '
'Metadata of archive members remain un-excluded. '
'Metadata of archive members remain un-excluded '
'except if "recursive" choice is set. '
'Use this option to ignore permissions, timestamps, '
'xattrs etc. Default: False if comparing two '
'directories, else True. Note that "file" metadata '
......@@ -469,12 +470,12 @@ def run_diffoscope(parsed_args):
file=sys.stderr)
return 1
else:
if Config().exclude_directory_metadata is None:
if Config().exclude_directory_metadata in ('auto', None):
# Default to ignoring metadata directory...
Config().exclude_directory_metadata = True
Config().exclude_directory_metadata = 'yes'
if os.path.isdir(path1) and os.path.isdir(path2):
# ... except if we passed two directories.
Config().exclude_directory_metadata = False
Config().exclude_directory_metadata = 'no'
logger.debug('Starting comparison')
with Progress():
......@@ -499,6 +500,14 @@ def main(args=None):
if args is None:
args = sys.argv[1:]
signal.signal(signal.SIGTERM, sigterm_handler)
# Rewrite/support some legacy argument styles
for val, repl in (
('--exclude-directory-metadata', '--exclude-directory-metadata=yes'),
('--no-exclude-directory-metadata', '--exclude-directory-metadata=no'),
):
args = [repl if x == val else x for x in args]
parsed_args = None
try:
with profile('main', 'parse_args'):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment