Skip to content

Commit

Permalink
Improve ros2 doctor on Windows (#631)
Browse files Browse the repository at this point in the history
Improve ros2 doctor on Windows:

* Print a more useful error message when failing to load plugin
* Print a clearer error message when failing to find either a loopback or no loopback interface on Windows.
* Print "latest version" instead of "required version".
* Print the corrent name of the python executable according to the platform.

Signed-off-by: Ivan Santiago Paunovic <ivanpauno@ekumenlabs.com>
Co-authored-by: Chris Lalancette <clalancette@openrobotics.org>
Co-authored-by: Christophe Bedard <bedard.christophe@gmail.com>
(cherry picked from commit 3803d77)
  • Loading branch information
ivanpauno authored and mergify-bot committed May 6, 2021
1 parent c4e005e commit 0675c95
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 39 deletions.
8 changes: 4 additions & 4 deletions ros2doctor/ros2doctor/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ def run_checks(*, include_warnings=False) -> Tuple[Set[str], int, int]:
for check_entry_pt in importlib_metadata.entry_points().get('ros2doctor.checks', []):
try:
check_class = check_entry_pt.load()
except ImportError:
doctor_warn(f'Check entry point {check_entry_pt.name} fails to load.')
except ImportError as e:
doctor_warn(f'Check entry point {check_entry_pt.name} fails to load: {e}')
continue
try:
check_instance = check_class()
Expand Down Expand Up @@ -123,8 +123,8 @@ def generate_reports(*, categories=None) -> List[Report]:
for report_entry_pt in importlib_metadata.entry_points().get('ros2doctor.report', []):
try:
report_class = report_entry_pt.load()
except ImportError:
doctor_warn(f'Report entry point {report_entry_pt.name} fails to load.')
except ImportError as e:
doctor_warn(f'Report entry point {report_entry_pt.name} fails to load: {e}')
continue
try:
report_instance = report_class()
Expand Down
33 changes: 8 additions & 25 deletions ros2doctor/ros2doctor/api/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,15 @@
import os
from typing import Tuple

import ifcfg

from ros2doctor.api import DoctorCheck
from ros2doctor.api import DoctorReport
from ros2doctor.api import Report
from ros2doctor.api import Result
from ros2doctor.api.format import doctor_error
from ros2doctor.api.format import doctor_warn

try:
import ifcfg
except ImportError: # check import error for windows and osx
doctor_warn(
'Unable to import ifcfg. '
'Use `python3 -m pip install ifcfg` to install needed package.')


def _is_unix_like_platform() -> bool:
"""Return True if conforms to UNIX/POSIX-style APIs."""
Expand Down Expand Up @@ -61,24 +56,16 @@ def check(self):
"""Check network configuration."""
result = Result()
# check ifcfg import for windows and osx users
try:
ifcfg_ifaces = ifcfg.interfaces()
except NameError:
doctor_error(
'`ifcfg` module is not imported. '
'Unable to run network check.')
result.add_error()
return result
ifcfg_ifaces = ifcfg.interfaces()

has_loopback, has_non_loopback, has_multicast = _check_network_config_helper(ifcfg_ifaces)
if not _is_unix_like_platform():
if not has_loopback and not has_non_loopback:
# no flags found, otherwise one of them should be True.
doctor_error(
'No flags found. '
'Run `ipconfig` on Windows or '
'install `ifconfig` on Unix to check network interfaces.')
result.add_error()
doctor_warn(
'Interface flags are not available on Windows. '
'Run `ipconfig` to see what interfaces are available.')
result.add_warning()
return result
if not has_loopback:
doctor_error('No loopback IP address is found.')
Expand All @@ -101,11 +88,7 @@ def category(self):
def report(self):
"""Print system and ROS network information."""
# check ifcfg import for windows and osx users
try:
ifcfg_ifaces = ifcfg.interfaces()
except NameError:
doctor_error('ifcfg is not imported. Unable to generate network report.')
return Report('')
ifcfg_ifaces = ifcfg.interfaces()

network_report = Report('NETWORK CONFIGURATION')
for iface in ifcfg_ifaces.values():
Expand Down
20 changes: 10 additions & 10 deletions ros2doctor/ros2doctor/api/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,26 +103,26 @@ def compare_versions(result: Result, local_packages: dict, distro_packages: dict
if not local_ver_str:
missing_local += ' ' + name
local_ver_str = ''
required_ver_str = distro_packages.get(name, '')
if not required_ver_str:
latest_ver_str = distro_packages.get(name, '')
if not latest_ver_str:
missing_req += ' ' + name
local_ver = version.parse(local_ver_str).base_version
required_ver = version.parse(required_ver_str).base_version
if local_ver < required_ver:
latest_ver = version.parse(latest_ver_str).base_version
if local_ver < latest_ver:
doctor_warn(
f'{name} has been updated to a new version.'
f' local: {local_ver} <'
f' required: {required_ver}')
f' latest: {latest_ver}')
result.add_warning()
if missing_req:
if len(missing_req) > 100:
doctor_warn(
'Cannot find required versions of packages: ' +
'Cannot find the latest versions of packages: ' +
textwrap.shorten(missing_req, width=100) +
' Use `ros2 doctor --report` to see full list.')
else:
doctor_warn(
'Cannot find required versions of packages: ' +
'Cannot find the latest versions of packages: ' +
missing_req)
if missing_local:
if len(missing_local) > 100:
Expand Down Expand Up @@ -174,8 +174,8 @@ def report(self):
if not local_package_vers or not distro_package_vers:
return report
for name, local_ver_str in local_package_vers.items():
required_ver_str = distro_package_vers.get(name, '')
latest_ver_str = distro_package_vers.get(name, '')
local_ver = version.parse(local_ver_str).base_version
required_ver = version.parse(required_ver_str).base_version
report.add_to_report(name, f'required={required_ver}, local={local_ver}')
latest_ver = version.parse(latest_ver_str).base_version
report.add_to_report(name, f'latest={latest_ver}, local={local_ver}')
return report

0 comments on commit 0675c95

Please sign in to comment.