Bug#855169: diffoscope: use BSD-style stat on FreeBSD

Ed Maste emaste at freebsd.org
Tue Feb 14 21:56:13 UTC 2017


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.
-------------- next part --------------
commit e709c11212a18105f3b6862d5ed20de61038b71a
Author: Ed Maste <emaste at 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')


More information about the Reproducible-builds mailing list