diff --git a/check-needles.py b/check-needles.py
new file mode 100755
index 00000000..83bea160
--- /dev/null
+++ b/check-needles.py
@@ -0,0 +1,146 @@
+#!/usr/bin/python3
+
+# Copyright (C) 2020 Red Hat
+#
+# This file is part of os-autoinst-distri-fedora.
+#
+# os-autoinst-distri-fedora is free software; you can redistribute it
+# and/or modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation, either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+#
+# Author: Adam Williamson
+
+"""This is a check script which checks for unused needles. If none of
+the tags a needle declares is referenced in the tests, it is
+considered unused.
+"""
+
+import glob
+import json
+import os
+import re
+import sys
+
+NEEDLEPATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "needles")
+TESTSPATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "tests")
+LIBPATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), "lib")
+# these don't account for escaping, but I don't think we're ever going
+# to have an escaped quotation mark in a needle tag
+DOUBLEQUOTERE = re.compile('"(.*?)"')
+SINGLEQUOTERE = re.compile("'(.*?)'")
+
+# first we're gonna build a big list of all string literals
+testpaths = glob.glob(f"{TESTSPATH}/**/*.pm", recursive=True)
+testpaths.extend(glob.glob(f"{LIBPATH}/**/*.pm", recursive=True))
+testliterals = []
+for testpath in testpaths:
+ # skip if it's a symlink
+ if os.path.islink(testpath):
+ continue
+ # otherwise, scan it for string literals
+ with open(testpath, "r") as testfh:
+ testtext = testfh.read()
+ for match in DOUBLEQUOTERE.finditer(testtext):
+ testliterals.append(match[1])
+ for match in SINGLEQUOTERE.finditer(testtext):
+ testliterals.append(match[1])
+
+# now let's do some whitelisting, for awkward cases where we know that
+# we concatenate string literals and stuff
+# versioned backgrounds and release IDs
+for rel in range(30, 100):
+ testliterals.append(f"{rel}_background")
+ testliterals.append(f"version_{rel}_ident")
+# anaconda id needles, using tell_source
+for source in ("workstation", "generic", "server"):
+ testliterals.append(f"leftbar_{source}")
+ testliterals.append(f"topbar_{source}")
+# keyboard layout switching, using desktop_switch_layout
+for environment in ("anaconda", "gnome"):
+ for layout in ("native", "ascii"):
+ testliterals.append(f"{environment}_layout_{layout}")
+# package set selection, using get_var('PACKAGE_SET')
+for pkgset in ("kde", "workstation", "minimal"):
+ testliterals.append(f"anaconda_{pkgset}_highlighted")
+ testliterals.append(f"anaconda_{pkgset}_selected")
+# partitioning stuff, there's a bunch of this, all in anaconda.pm
+# multiple things use this
+for part in ("swap", "root"):
+ testliterals.append(f"anaconda_part_select_{part}")
+# select_disks
+for num in range(1, 10):
+ testliterals.append(f"anaconda_install_destination_select_disk_{num}")
+# custom_scheme_select
+for scheme in ("standard", "lvmthin", "btrfs"):
+ testliterals.append(f"anaconda_part_scheme_{scheme}")
+# custom_blivet_add_partition
+for dtype in ("lvm", "lvmthin", "raid"):
+ testliterals.append(f"anaconda_blivet_part_devicetype_{dtype}")
+for fsys in ("ext3", "ext4", "xfs", "btrfs", "ppc_prep_boot", "swap", "efi_filesystem"):
+ testliterals.append(f"anaconda_blivet_part_fs_{fsys}")
+ testliterals.append(f"anaconda_blivet_part_fs_{fsys}_selected")
+# this is variable-y in custom_change_type but we only actually have
+# one value
+testliterals.append("anaconda_part_device_type_raid")
+# custom_change_fs
+for fsys in ("ext3", "xfs"):
+ testliterals.append(f"anaconda_part_fs_{fsys}")
+ testliterals.append(f"anaconda_part_fs_{fsys}_selected")
+# variable-y in custom_change_device but we only have one value
+testliterals.append("anaconda_part_device_sda")
+
+# retcode tracker
+ret = 0
+
+# now let's scan our needles
+unused = []
+noimg = []
+noneedle = []
+
+needlepaths = glob.glob(f"{NEEDLEPATH}/**/*.json", recursive=True)
+for needlepath in needlepaths:
+ # check we have a matching image file
+ imgpath = needlepath.replace(".json", ".png")
+ if not os.path.exists(imgpath):
+ noimg.append(needlepath)
+ with open(needlepath, "r") as needlefh:
+ needlejson = json.load(needlefh)
+ if any(tag in testliterals for tag in needlejson["tags"]):
+ continue
+ unused.append(needlepath)
+
+# reverse check, for images without a needle file
+imgpaths = glob.glob(f"{NEEDLEPATH}/**/*.png", recursive=True)
+for imgpath in imgpaths:
+ needlepath = imgpath.replace(".png", ".json")
+ if not os.path.exists(needlepath):
+ noneedle.append(imgpath)
+
+if unused:
+ ret += 1
+ print("Unused needle(s) found!")
+ for needle in unused:
+ print(needle)
+
+if noimg:
+ ret += 2
+ print("Needle(s) without image(s) found!")
+ for needle in noimg:
+ print(needle)
+
+if noneedle:
+ ret += 4
+ print("Image(s) without needle(s) found!")
+ for img in noneedle:
+ print(img)
+
+sys.exit(ret)
diff --git a/needles/anaconda/install_destination/reclaim_space_second_partition.json b/needles/anaconda/install_destination/reclaim_space_second_partition.json
deleted file mode 100644
index 0ffd05e3..00000000
--- a/needles/anaconda/install_destination/reclaim_space_second_partition.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "area": [
- {
- "xpos": 11,
- "ypos": 301,
- "width": 75,
- "height": 25,
- "type": "match"
- }
- ],
- "tags": [
- "anaconda_install_destination_reclaim_space_second_partition",
- "ENV-DISTRI-fedora",
- "ENV-FLAVOR-server"
- ]
-}
diff --git a/needles/anaconda/install_destination/reclaim_space_second_partition.png b/needles/anaconda/install_destination/reclaim_space_second_partition.png
deleted file mode 100644
index 853f509c..00000000
Binary files a/needles/anaconda/install_destination/reclaim_space_second_partition.png and /dev/null differ
diff --git a/needles/anaconda/install_process/french/user_creation_password_input_french.json b/needles/anaconda/install_process/french/user_creation_password_input_french.json
deleted file mode 100644
index 9ffbfea0..00000000
--- a/needles/anaconda/install_process/french/user_creation_password_input_french.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "area": [
- {
- "height": 25,
- "type": "match",
- "width": 268,
- "xpos": 250,
- "ypos": 285
- }
- ],
- "properties": [],
- "tags": [
- "anaconda_user_creation_password_input",
- "ENV-DISTRI-fedora",
- "LANGUAGE-french",
- "ENV-FLAVOR-server"
- ]
-}
\ No newline at end of file
diff --git a/needles/anaconda/install_process/french/user_creation_password_input_french.png b/needles/anaconda/install_process/french/user_creation_password_input_french.png
deleted file mode 100644
index 2efb9604..00000000
Binary files a/needles/anaconda/install_process/french/user_creation_password_input_french.png and /dev/null differ
diff --git a/needles/anaconda/install_process/russian/user_creation_password_input_russian.json b/needles/anaconda/install_process/russian/user_creation_password_input_russian.json
deleted file mode 100644
index 64a3d34f..00000000
--- a/needles/anaconda/install_process/russian/user_creation_password_input_russian.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "tags": [
- "LANGUAGE-russian",
- "anaconda_user_creation_password_input"
- ],
- "area": [
- {
- "xpos": 287,
- "ypos": 279,
- "width": 251,
- "height": 18,
- "type": "match"
- }
- ],
- "properties": []
-}
\ No newline at end of file
diff --git a/needles/anaconda/install_process/russian/user_creation_password_input_russian.png b/needles/anaconda/install_process/russian/user_creation_password_input_russian.png
deleted file mode 100644
index 1f9e2140..00000000
Binary files a/needles/anaconda/install_process/russian/user_creation_password_input_russian.png and /dev/null differ
diff --git a/needles/anaconda/install_process/user_creation_password_input-cantarell21.json b/needles/anaconda/install_process/user_creation_password_input-cantarell21.json
deleted file mode 100644
index ffc5929b..00000000
--- a/needles/anaconda/install_process/user_creation_password_input-cantarell21.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "area": [
- {
- "height": 25,
- "type": "match",
- "width": 243,
- "xpos": 260,
- "ypos": 276
- }
- ],
- "properties": [],
- "tags": [
- "anaconda_user_creation_password_input",
- "ENV-DISTRI-fedora",
- "LANGUAGE-english",
- "ENV-FLAVOR-server"
- ]
-}
\ No newline at end of file
diff --git a/needles/anaconda/install_process/user_creation_password_input-cantarell21.png b/needles/anaconda/install_process/user_creation_password_input-cantarell21.png
deleted file mode 100644
index c7c689ec..00000000
Binary files a/needles/anaconda/install_process/user_creation_password_input-cantarell21.png and /dev/null differ
diff --git a/needles/anaconda/partitioning/add_mountpoint.json b/needles/anaconda/partitioning/add_mountpoint.json
deleted file mode 100644
index 1fe6a672..00000000
--- a/needles/anaconda/partitioning/add_mountpoint.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "properties": [],
- "area": [
- {
- "xpos": 545,
- "ypos": 461,
- "width": 118,
- "height": 26,
- "type": "match"
- }
- ],
- "tags": [
- "anaconda_part_add_mountpoint",
- "ENV-DISTRI-fedora",
- "LANGUAGE-english",
- "ENV-FLAVOR-server"
- ]
-}
\ No newline at end of file
diff --git a/needles/anaconda/partitioning/add_mountpoint.png b/needles/anaconda/partitioning/add_mountpoint.png
deleted file mode 100644
index 91fe79be..00000000
Binary files a/needles/anaconda/partitioning/add_mountpoint.png and /dev/null differ
diff --git a/needles/anaconda/partitioning/desired_capacity.json b/needles/anaconda/partitioning/desired_capacity.json
deleted file mode 100644
index a2e5188d..00000000
--- a/needles/anaconda/partitioning/desired_capacity.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "area": [
- {
- "xpos": 351,
- "ypos": 406,
- "width": 304,
- "height": 21,
- "type": "match"
- }
- ],
- "tags": [
- "anaconda_part_desired_capacity",
- "ENV-DISTRI-fedora",
- "LANGUAGE-english",
- "ENV-FLAVOR-server"
- ],
- "properties": []
-}
\ No newline at end of file
diff --git a/needles/anaconda/partitioning/desired_capacity.png b/needles/anaconda/partitioning/desired_capacity.png
deleted file mode 100644
index 91fe79be..00000000
Binary files a/needles/anaconda/partitioning/desired_capacity.png and /dev/null differ
diff --git a/needles/anaconda/partitioning/list_box_boot.json b/needles/anaconda/partitioning/list_box_boot.json
deleted file mode 100644
index 68fc83a3..00000000
--- a/needles/anaconda/partitioning/list_box_boot.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "tags": [
- "anaconda_part_list_box_boot",
- "ENV-DISTRI-fedora",
- "ENV-FLAVOR-server"
- ],
- "area": [
- {
- "xpos": 471,
- "ypos": 433,
- "width": 63,
- "height": 28,
- "type": "match"
- }
- ],
- "properties": []
-}
diff --git a/needles/anaconda/partitioning/list_box_boot.png b/needles/anaconda/partitioning/list_box_boot.png
deleted file mode 100644
index 00cdbdaf..00000000
Binary files a/needles/anaconda/partitioning/list_box_boot.png and /dev/null differ
diff --git a/needles/anaconda/partitioning/list_box_button.json b/needles/anaconda/partitioning/list_box_button.json
deleted file mode 100644
index 331dd901..00000000
--- a/needles/anaconda/partitioning/list_box_button.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "properties": [],
- "tags": [
- "anaconda_part_list_box_button",
- "ENV-DISTRI-fedora",
- "ENV-FLAVOR-server"
- ],
- "area": [
- {
- "xpos": 640,
- "ypos": 372,
- "width": 27,
- "height": 22,
- "type": "match"
- }
- ]
-}
diff --git a/needles/anaconda/partitioning/list_box_button.png b/needles/anaconda/partitioning/list_box_button.png
deleted file mode 100644
index 91fe79be..00000000
Binary files a/needles/anaconda/partitioning/list_box_button.png and /dev/null differ
diff --git a/needles/anaconda/partitioning/list_box_root.json b/needles/anaconda/partitioning/list_box_root.json
deleted file mode 100644
index a255d5fc..00000000
--- a/needles/anaconda/partitioning/list_box_root.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "properties": [],
- "tags": [
- "anaconda_part_list_box_root",
- "ENV-DISTRI-fedora",
- "ENV-FLAVOR-server"
- ],
- "area": [
- {
- "xpos": 472,
- "ypos": 405,
- "width": 66,
- "height": 26,
- "type": "match"
- }
- ]
-}
diff --git a/needles/anaconda/partitioning/list_box_root.png b/needles/anaconda/partitioning/list_box_root.png
deleted file mode 100644
index 00cdbdaf..00000000
Binary files a/needles/anaconda/partitioning/list_box_root.png and /dev/null differ
diff --git a/needles/anaconda/partitioning/list_box_swap.json b/needles/anaconda/partitioning/list_box_swap.json
deleted file mode 100644
index c355f3d7..00000000
--- a/needles/anaconda/partitioning/list_box_swap.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "area": [
- {
- "height": 24,
- "type": "match",
- "width": 91,
- "xpos": 472,
- "ypos": 528
- }
- ],
- "properties": [],
- "tags": [
- "anaconda_part_list_box_swap",
- "ENV-DISTRI-fedora",
- "ENV-FLAVOR-server"
- ]
-}
diff --git a/needles/anaconda/partitioning/list_box_swap.png b/needles/anaconda/partitioning/list_box_swap.png
deleted file mode 100644
index 00cdbdaf..00000000
Binary files a/needles/anaconda/partitioning/list_box_swap.png and /dev/null differ
diff --git a/needles/anaconda/partitioning/plus_button.json b/needles/anaconda/partitioning/plus_button.json
deleted file mode 100644
index cc09a5f0..00000000
--- a/needles/anaconda/partitioning/plus_button.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "area": [
- {
- "height": 31,
- "type": "match",
- "width": 35,
- "xpos": 32,
- "ypos": 619
- }
- ],
- "properties": [],
- "tags": [
- "anaconda_part_plus_button",
- "ENV-DISTRI-fedora",
- "ENV-FLAVOR-server"
- ]
-}
diff --git a/needles/anaconda/partitioning/plus_button.png b/needles/anaconda/partitioning/plus_button.png
deleted file mode 100644
index 6438d361..00000000
Binary files a/needles/anaconda/partitioning/plus_button.png and /dev/null differ
diff --git a/needles/anaconda/partitioning/scheme_lvm.json b/needles/anaconda/partitioning/scheme_lvm.json
deleted file mode 100644
index 9f8c9198..00000000
--- a/needles/anaconda/partitioning/scheme_lvm.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "area": [
- {
- "height": 20,
- "type": "match",
- "width": 35,
- "xpos": 60,
- "ypos": 300
- }
- ],
- "tags": [
- "anaconda_part_scheme_lvm",
- "ENV-DISTRI-fedora",
- "ENV-FLAVOR-server"
- ]
-}
diff --git a/needles/anaconda/partitioning/scheme_lvm.png b/needles/anaconda/partitioning/scheme_lvm.png
deleted file mode 100644
index dda82fd2..00000000
Binary files a/needles/anaconda/partitioning/scheme_lvm.png and /dev/null differ
diff --git a/needles/cockpit/cockpit_updates_available.json b/needles/cockpit/cockpit_updates_available.json
deleted file mode 100644
index 3c41539b..00000000
--- a/needles/cockpit/cockpit_updates_available.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "cockpit_updates_available"
- ],
- "area": [
- {
- "xpos": 264,
- "ypos": 259,
- "width": 185,
- "height": 28,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/cockpit/cockpit_updates_available.png b/needles/cockpit/cockpit_updates_available.png
deleted file mode 100644
index e4784aef..00000000
Binary files a/needles/cockpit/cockpit_updates_available.png and /dev/null differ
diff --git a/needles/cockpit/cockpit_updates_console_update.json b/needles/cockpit/cockpit_updates_console_update.json
deleted file mode 100644
index 0c7d9b61..00000000
--- a/needles/cockpit/cockpit_updates_console_update.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "area": [
- {
- "xpos": 304,
- "ypos": 309,
- "width": 143,
- "height": 17,
- "type": "match"
- }
- ],
- "properties": [],
- "tags": [
- "cockpit_updates_console_update"
- ]
-}
\ No newline at end of file
diff --git a/needles/cockpit/cockpit_updates_console_update.png b/needles/cockpit/cockpit_updates_console_update.png
deleted file mode 100644
index 496616c6..00000000
Binary files a/needles/cockpit/cockpit_updates_console_update.png and /dev/null differ
diff --git a/needles/cockpit/cockpit_updates_restart_confirm.json b/needles/cockpit/cockpit_updates_restart_confirm.json
deleted file mode 100644
index bad9aab8..00000000
--- a/needles/cockpit/cockpit_updates_restart_confirm.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "cockpit_updates_restart_confirm"
- ],
- "area": [
- {
- "xpos": 576,
- "ypos": 260,
- "width": 46,
- "height": 15,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/cockpit/cockpit_updates_restart_confirm.png b/needles/cockpit/cockpit_updates_restart_confirm.png
deleted file mode 100644
index 9a5f2d7c..00000000
Binary files a/needles/cockpit/cockpit_updates_restart_confirm.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_first_services.png b/needles/gnome/apps/apps_first_services.png
deleted file mode 100644
index 75d56c7a..00000000
Binary files a/needles/gnome/apps/apps_first_services.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_menu_documents.json b/needles/gnome/apps/apps_menu_documents.json
deleted file mode 100644
index 91feaba6..00000000
--- a/needles/gnome/apps/apps_menu_documents.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "apps_menu_documents"
- ],
- "area": [
- {
- "xpos": 491,
- "ypos": 298,
- "width": 36,
- "height": 47,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/gnome/apps/apps_menu_documents.png b/needles/gnome/apps/apps_menu_documents.png
deleted file mode 100644
index 93623931..00000000
Binary files a/needles/gnome/apps/apps_menu_documents.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_menu_settings-20200316.json b/needles/gnome/apps/apps_menu_settings-20200316.json
deleted file mode 100644
index fa67f7d1..00000000
--- a/needles/gnome/apps/apps_menu_settings-20200316.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "apps_menu_settings"
- ],
- "area": [
- {
- "xpos": 756,
- "ypos": 446,
- "width": 61,
- "height": 43,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/gnome/apps/apps_menu_settings-20200316.png b/needles/gnome/apps/apps_menu_settings-20200316.png
deleted file mode 100644
index 2b7be422..00000000
Binary files a/needles/gnome/apps/apps_menu_settings-20200316.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_menu_settings.json b/needles/gnome/apps/apps_menu_settings.json
deleted file mode 100644
index 4c8d72a8..00000000
--- a/needles/gnome/apps/apps_menu_settings.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "apps_menu_settings"
- ],
- "area": [
- {
- "xpos": 634,
- "ypos": 583,
- "width": 37,
- "height": 37,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/gnome/apps/apps_menu_settings.png b/needles/gnome/apps/apps_menu_settings.png
deleted file mode 100644
index 93623931..00000000
Binary files a/needles/gnome/apps/apps_menu_settings.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_menu_terminal-20190128.json b/needles/gnome/apps/apps_menu_terminal-20190128.json
deleted file mode 100644
index 54432592..00000000
--- a/needles/gnome/apps/apps_menu_terminal-20190128.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "apps_menu_terminal"
- ],
- "area": [
- {
- "xpos": 207,
- "height": 32,
- "width": 45,
- "type": "match",
- "ypos": 588
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/gnome/apps/apps_menu_terminal-20190128.png b/needles/gnome/apps/apps_menu_terminal-20190128.png
deleted file mode 100644
index 8c9ea0a7..00000000
Binary files a/needles/gnome/apps/apps_menu_terminal-20190128.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_menu_terminal-20200316.json b/needles/gnome/apps/apps_menu_terminal-20200316.json
deleted file mode 100644
index c65582ba..00000000
--- a/needles/gnome/apps/apps_menu_terminal-20200316.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "apps_menu_terminal"
- ],
- "area": [
- {
- "xpos": 574,
- "ypos": 567,
- "width": 59,
- "height": 38,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/gnome/apps/apps_menu_terminal-20200316.png b/needles/gnome/apps/apps_menu_terminal-20200316.png
deleted file mode 100644
index 25e97da6..00000000
Binary files a/needles/gnome/apps/apps_menu_terminal-20200316.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_menu_terminal.json b/needles/gnome/apps/apps_menu_terminal.json
deleted file mode 100644
index 0ffaf094..00000000
--- a/needles/gnome/apps/apps_menu_terminal.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "apps_menu_terminal"
- ],
- "area": [
- {
- "xpos": 209,
- "ypos": 591,
- "width": 45,
- "height": 32,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/gnome/apps/apps_menu_terminal.png b/needles/gnome/apps/apps_menu_terminal.png
deleted file mode 100644
index 9fb2dd37..00000000
Binary files a/needles/gnome/apps/apps_menu_terminal.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_run_clocks_access.json b/needles/gnome/apps/apps_run_clocks_access.json
deleted file mode 100644
index 03b00b2f..00000000
--- a/needles/gnome/apps/apps_run_clocks_access.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "apps_run_clocks_access"
- ],
- "area": [
- {
- "xpos": 602,
- "ypos": 478,
- "width": 105,
- "height": 21,
- "type": "ocr"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/gnome/apps/apps_run_clocks_access.png b/needles/gnome/apps/apps_run_clocks_access.png
deleted file mode 100644
index 7bd1c212..00000000
Binary files a/needles/gnome/apps/apps_run_clocks_access.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_run_documents.json b/needles/gnome/apps/apps_run_documents.json
deleted file mode 100644
index 2a439bbb..00000000
--- a/needles/gnome/apps/apps_run_documents.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "apps_run_documents"
- ],
- "area": [
- {
- "xpos": 412,
- "ypos": 39,
- "width": 79,
- "height": 23,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/gnome/apps/apps_run_documents.png b/needles/gnome/apps/apps_run_documents.png
deleted file mode 100644
index 4f979c13..00000000
Binary files a/needles/gnome/apps/apps_run_documents.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_run_nautilus.json b/needles/gnome/apps/apps_run_nautilus.json
deleted file mode 100644
index a6002546..00000000
--- a/needles/gnome/apps/apps_run_nautilus.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "apps_run_nautilus"
- ],
- "area": [
- {
- "xpos": 157,
- "ypos": 86,
- "width": 67,
- "height": 23,
- "type": "ocr"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/gnome/apps/apps_run_nautilus.png b/needles/gnome/apps/apps_run_nautilus.png
deleted file mode 100644
index 6218a22a..00000000
Binary files a/needles/gnome/apps/apps_run_nautilus.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_run_settings.json b/needles/gnome/apps/apps_run_settings.json
deleted file mode 100644
index e64ba22c..00000000
--- a/needles/gnome/apps/apps_run_settings.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "apps_run_settings"
- ],
- "area": [
- {
- "xpos": 104,
- "ypos": 41,
- "width": 61,
- "height": 21,
- "type": "ocr"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/gnome/apps/apps_run_settings.png b/needles/gnome/apps/apps_run_settings.png
deleted file mode 100644
index 02427f9b..00000000
Binary files a/needles/gnome/apps/apps_run_settings.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_run_weather_access.json b/needles/gnome/apps/apps_run_weather_access.json
deleted file mode 100644
index 749dada0..00000000
--- a/needles/gnome/apps/apps_run_weather_access.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "apps_run_weather_access"
- ],
- "area": [
- {
- "xpos": 601,
- "ypos": 474,
- "width": 105,
- "height": 27,
- "type": "ocr"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/gnome/apps/apps_run_weather_access.png b/needles/gnome/apps/apps_run_weather_access.png
deleted file mode 100644
index bc1b4961..00000000
Binary files a/needles/gnome/apps/apps_run_weather_access.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_sub_utilities.json b/needles/gnome/apps/apps_sub_utilities.json
deleted file mode 100644
index a46acd40..00000000
--- a/needles/gnome/apps/apps_sub_utilities.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "apps_sub_utilities"
- ],
- "area": [
- {
- "xpos": 616,
- "ypos": 159,
- "width": 71,
- "height": 58,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/gnome/apps/apps_sub_utilities.png b/needles/gnome/apps/apps_sub_utilities.png
deleted file mode 100644
index 9fb2dd37..00000000
Binary files a/needles/gnome/apps/apps_sub_utilities.png and /dev/null differ
diff --git a/needles/gnome/apps/apps_utilities.json b/needles/gnome/apps/apps_utilities.json
deleted file mode 100644
index 0e5edf6e..00000000
--- a/needles/gnome/apps/apps_utilities.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "apps_utilities"
- ],
- "area": [
- {
- "xpos": 463,
- "ypos": 154,
- "width": 100,
- "height": 37,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/gnome/apps/apps_utilities.png b/needles/gnome/apps/apps_utilities.png
deleted file mode 100644
index 0a7813d6..00000000
Binary files a/needles/gnome/apps/apps_utilities.png and /dev/null differ
diff --git a/needles/kde/apps/firewall_requires.json b/needles/kde/apps/firewall_requires.json
deleted file mode 100644
index 13e7c3fa..00000000
--- a/needles/kde/apps/firewall_requires.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "firewall_requires"
- ],
- "area": [
- {
- "xpos": 595,
- "ypos": 422,
- "width": 19,
- "height": 16,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/kde/apps/firewall_requires.png b/needles/kde/apps/firewall_requires.png
deleted file mode 100644
index fd315869..00000000
Binary files a/needles/kde/apps/firewall_requires.png and /dev/null differ
diff --git a/needles/kde/apps/kamoso_runs.json b/needles/kde/apps/kamoso_runs.json
deleted file mode 100644
index 74903bd7..00000000
--- a/needles/kde/apps/kamoso_runs.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "kamoso_runs"
- ],
- "area": [
- {
- "xpos": 322,
- "ypos": 9,
- "width": 58,
- "height": 15,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/kde/apps/kamoso_runs.png b/needles/kde/apps/kamoso_runs.png
deleted file mode 100644
index 7d19eb0a..00000000
Binary files a/needles/kde/apps/kamoso_runs.png and /dev/null differ
diff --git a/needles/kde/apps/menu_favorites.json b/needles/kde/apps/menu_favorites.json
deleted file mode 100644
index 6ef5b11b..00000000
--- a/needles/kde/apps/menu_favorites.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "menu_favorites"
- ],
- "area": [
- {
- "xpos": 37,
- "ypos": 654,
- "width": 36,
- "height": 31,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/kde/apps/menu_favorites.png b/needles/kde/apps/menu_favorites.png
deleted file mode 100644
index 6d024c39..00000000
Binary files a/needles/kde/apps/menu_favorites.png and /dev/null differ
diff --git a/needles/kde/apps/users_runs.json b/needles/kde/apps/users_runs.json
deleted file mode 100644
index f4b1dae3..00000000
--- a/needles/kde/apps/users_runs.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
- "properties": [],
- "tags": [
- "users_runs"
- ],
- "area": [
- {
- "xpos": 468,
- "ypos": 116,
- "width": 96,
- "height": 19,
- "type": "match"
- }
- ]
-}
\ No newline at end of file
diff --git a/needles/kde/apps/users_runs.png b/needles/kde/apps/users_runs.png
deleted file mode 100644
index 13a0f9d8..00000000
Binary files a/needles/kde/apps/users_runs.png and /dev/null differ
diff --git a/tox.ini b/tox.ini
index 5a2a84ab..601b9697 100644
--- a/tox.ini
+++ b/tox.ini
@@ -13,6 +13,7 @@ deps =
commands=
./fifloader.py --clean templates.fif.json templates-updates.fif.json
+ ./check-needles.py
py.test unittests/
py.test --cov-report term-missing --cov-report xml --cov fifloader unittests/
diff-cover coverage.xml --fail-under=90