From 284f6f1ef812f9561c150ca28b06f91a44f7a09c Mon Sep 17 00:00:00 2001
From: Benjamin Berg <bberg@redhat.com>
Date: Tue, 19 Jan 2021 15:55:56 +0100
Subject: [PATCH] ci: Add check that wiki and generator are in sync

Add a new test that checks that the unsupported list is not out of date.
As the wiki can be edited at any time, add this as a further optional
check into the CI pipeline.
---
 .gitlab-ci.yml                  |  9 ++++++
 tests/hwdb-check-unsupported.py | 54 +++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)
 create mode 100755 tests/hwdb-check-unsupported.py

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c416c2b..4f56ec7 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -112,6 +112,15 @@ test_indent:
     - git diff
     - "! git status -s | grep -q ."
 
+test_unsupported_list:
+  stage: check-source
+  except:
+    variables:
+      - $CI_PIPELINE_SOURCE == "schedule"
+  allow_failure: true
+  script:
+    - tests/hwdb-check-unsupported.py
+
 flatpak:
   stage: flatpak
   extends: .flatpak
diff --git a/tests/hwdb-check-unsupported.py b/tests/hwdb-check-unsupported.py
new file mode 100755
index 0000000..650cd09
--- /dev/null
+++ b/tests/hwdb-check-unsupported.py
@@ -0,0 +1,54 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import urllib
+import urllib.request
+import re
+
+error = False
+
+try:
+    response = urllib.request.urlopen('https://gitlab.freedesktop.org/libfprint/wiki/-/wikis/Unsupported-Devices.md')
+except:
+    print("Could not download current list of unsupported devices, skipping test.")
+    sys.exit(77)
+data = response.read().decode('utf-8')
+
+devices = []
+devices_re = re.compile(r'^.*([0-9a-fA-F]{4}):([0-9a-fA-F]{4}).*$', re.MULTILINE)
+for m in devices_re.finditer(data):
+    vid = m.group(1)
+    pid = m.group(2)
+    devices.append((vid, pid))
+
+generator = open(os.path.join(os.path.dirname(__file__), '..', 'libfprint', 'fprint-list-udev-hwdb.c')).read()
+
+id_re = re.compile('  { .vid = 0x([a-fA-F0-9]*), .pid = 0x([a-fA-F0-9]*) }')
+# Check everything is the same
+started = False
+for l in generator.split('\n'):
+    m = id_re.match(l)
+    if m is None:
+        # Stop on the first line that does not match anymore
+        if started:
+            break
+        continue
+    else:
+        started = True
+
+    vid_pid = (m.group(1), m.group(2))
+    try:
+        devices.remove(vid_pid)
+    except ValueError:
+        print("Generator has entry that is not on wiki: {}:{}".format(*vid_pid))
+        error = True
+
+for vid_pid in devices:
+    print("New entry from wiki is missing: {}:{}".format(*vid_pid))
+    error = True
+
+if error:
+    sys.exit(1)
+else:
+    sys.exit(0)