Package: diffoscope Version: 77 >From GNU stat output diffoscope filters those parts that are allowed to change. The BSD stat(1) command does not match the output format and reports undesired differences:
% python3 setup.py test --pytest-args="-rsx -l -vv tests/test_main.py::test_no_differences_directories" ... > assert ret == 0 E assert 1 == 0 capsys = <_pytest.capture.CaptureFixture object at 0x806b08c18> create_dir = <function test_no_differences_directories.<locals>.create_dir at 0x808576b70> err = '' out = '--- /tmp/pytest-of-emaste/pytest-13/test_no_differences_directorie0/a\n+++ /tmp/pytest-of-emaste/pytest-13/test_no_di...14 21:49:59 2017" "Jan 1 00:00:00 1970" 32768 8 0 /tmp/pytest-of-emaste/pytest-13/test_no_differences_directorie0/b\n' ret = 1 ... BSD stat accepts a -f argument to specify the output format so the filtering can be avoided altogether. Attached patch (also available as https://github.com/emaste/diffoscope/commit/e709c11212a18105f3b6862d5ed20de61038b71a) is my approach at addressing this.
commit e709c11212a18105f3b6862d5ed20de61038b71a Author: Ed Maste <ema...@freebsd.org> Date: Tue Feb 14 16:42:20 2017 -0500 Assume BSD-style stat(1) on FreeBSD diff --git a/diffoscope/comparators/directory.py b/diffoscope/comparators/directory.py index d30cb64..1327912 100644 --- a/diffoscope/comparators/directory.py +++ b/diffoscope/comparators/directory.py @@ -45,25 +45,31 @@ def list_files(path): return all_files -class Stat(Command): - @tool_required('stat') - def cmdline(self): - return ['stat', self.path] - - FILE_RE = re.compile(r'^\s*File:.*$') - DEVICE_RE = re.compile(r'Device: [0-9a-f]+h/[0-9]+d\s+') - INODE_RE = re.compile(r'Inode: [0-9]+\s+') - ACCESS_TIME_RE = re.compile(r'^Access: [0-9]{4}-[0-9]{2}-[0-9]{2}.*$') - CHANGE_TIME_RE = re.compile(r'^Change: [0-9]{4}-[0-9]{2}-[0-9]{2}.*$') - - def filter(self, line): - line = line.decode('utf-8') - line = Stat.FILE_RE.sub('', line) - line = Stat.DEVICE_RE.sub('', line) - line = Stat.INODE_RE.sub('', line) - line = Stat.ACCESS_TIME_RE.sub('', line) - line = Stat.CHANGE_TIME_RE.sub('', line) - return line.encode('utf-8') +if os.uname()[0] == 'FreeBSD': + class Stat(Command): + @tool_required('stat') + def cmdline(self): + return ['stat', '-t', '%Y-%m-%d %H:%M:%S', '-f', '%Sp %l %Su %Sg %z %Sm %k %b %#Xf', self.path] +else: + class Stat(Command): + @tool_required('stat') + def cmdline(self): + return ['stat', self.path] + + FILE_RE = re.compile(r'^\s*File:.*$') + DEVICE_RE = re.compile(r'Device: [0-9a-f]+h/[0-9]+d\s+') + INODE_RE = re.compile(r'Inode: [0-9]+\s+') + ACCESS_TIME_RE = re.compile(r'^Access: [0-9]{4}-[0-9]{2}-[0-9]{2}.*$') + CHANGE_TIME_RE = re.compile(r'^Change: [0-9]{4}-[0-9]{2}-[0-9]{2}.*$') + + def filter(self, line): + line = line.decode('utf-8') + line = Stat.FILE_RE.sub('', line) + line = Stat.DEVICE_RE.sub('', line) + line = Stat.INODE_RE.sub('', line) + line = Stat.ACCESS_TIME_RE.sub('', line) + line = Stat.CHANGE_TIME_RE.sub('', line) + return line.encode('utf-8') @tool_required('lsattr')