anon-iclr-submission/benchname-bug-localization huggingface dataset:
Repository: bitcoin-core/hwi
Issue: Command installudevrules fails when udevadm is not in /sbin

Ubuntu 20.04.1 places `udevadm` in `/usr/bin/` rather than `/sbin`, causing `installudevrules` to fail with
```
{"error": "installudevrules failed: [Errno 2] No such file or directory: '/sbin/udevadm'", "code": -13}
```

Ideally, hwi would detect the location with `which udevadm` before calling it (and `groupadd` and `usermod` as well).

Changed files:
hwilib/udevinstaller.py

diff --git a/hwilib/udevinstaller.py b/hwilib/udevinstaller.py
index 4c32437..38129fe 100644
--- a/hwilib/udevinstaller.py
+++ b/hwilib/udevinstaller.py
@@ -8,7 +8,7 @@ Classes and utilities for installing device udev rules.
 from .errors import NeedsRootError
 
 from subprocess import check_call, CalledProcessError, DEVNULL
-from shutil import copy
+from shutil import copy, which
 from os import path, listdir, getlogin, geteuid
 
 class UDevInstaller(object):
@@ -39,9 +39,9 @@ class UDevInstaller(object):
         return True
 
     def __init__(self) -> None:
-        self._udevadm = '/sbin/udevadm'
-        self._groupadd = '/usr/sbin/groupadd'
-        self._usermod = '/usr/sbin/usermod'
+        self._udevadm = which('udevadm')
+        self._groupadd = which('groupadd')
+        self._usermod = which('usermod')
 
     def _execute(self, cmd: str, *args: str) -> None:
         command = [cmd] + list(args)
@@ -51,12 +51,14 @@ class UDevInstaller(object):
         """
         Run ``udevadm trigger``
         """
+        assert self._udevadm
         self._execute(self._udevadm, 'trigger')
 
     def reload_rules(self) -> None:
         """
         Run ``udevadm control --reload-rules``
         """
+        assert self._udevadm
         self._execute(self._udevadm, 'control', '--reload-rules')
 
     def add_user_plugdev_group(self) -> None:
@@ -67,6 +69,7 @@ class UDevInstaller(object):
         self._add_user_to_group(getlogin(), 'plugdev')
 
     def _create_group(self, name: str) -> None:
+        assert self._groupadd
         try:
             self._execute(self._groupadd, name)
         except CalledProcessError as e:
@@ -74,6 +77,7 @@ class UDevInstaller(object):
                 raise
 
     def _add_user_to_group(self, user: str, group: str) -> None:
+        assert self._usermod
         self._execute(self._usermod, '-aG', group, user)
 
     def copy_udev_rule_files(self, source: str, location: str) -> None:
Repository: bitcoin-core/hwi
Issue: Improve dependency checking

If you do `pip3 uninstall mnemonic` then `./hwi.py enumerate` will return an empty array (at least with a Trezor).

Changed files:
hwilib/commands.py

diff --git a/hwilib/commands.py b/hwilib/commands.py
index a6f762c..91d347c 100644
--- a/hwilib/commands.py
+++ b/hwilib/commands.py
@@ -19,6 +19,7 @@ For more information about the exceptions that those can raise, please see the s
 """
 
 import importlib
+import logging
 import platform
 
 from ._base58 import xpub_to_pub_hex
@@ -109,8 +110,11 @@ def enumerate(password: str = "") -> List[Dict[str, Any]]:
         try:
             imported_dev = importlib.import_module('.devices.' + module, __package__)
             result.extend(imported_dev.enumerate(password)) # type: ignore
-        except ImportError:
-            pass # Ignore ImportErrors, the user may not have all device dependencies installed
+        except ImportError as e:
+            # Warn for ImportErrors, but largely ignore them to allow users not install
+            # all device dependencies if only one or some devices are wanted.
+            logging.warn(f"{e}, required for {module}. Ignore if you do not want this device.")
+            pass
     return result
 
 # Fingerprint or device type required