Skip to content

Commit 3ff2adb

Browse files
author
Claire Wang
authored
Add distribution check and report feature to ros2 doctor command (#311)
* created ros2debug package Signed-off-by: clairewangosrf <[email protected]> Signed-off-by: claireyywang <[email protected]> * created setup verb, need revision Signed-off-by: clairewangosrf <[email protected]> Signed-off-by: claireyywang <[email protected]> * added simple setup check Signed-off-by: clairewangosrf <[email protected]> Signed-off-by: claireyywang <[email protected]> * added simple setup check, need testing Signed-off-by: clairewangosrf <[email protected]> Signed-off-by: claireyywang <[email protected]> * added four standard tests Signed-off-by: clairewangosrf <[email protected]> Signed-off-by: claireyywang <[email protected]> * add new line to end of file Signed-off-by: clairewangosrf <[email protected]> Signed-off-by: claireyywang <[email protected]> * corrected code format Signed-off-by: clairewangosrf <[email protected]> Signed-off-by: claireyywang <[email protected]> * update debug api Signed-off by: Claire Wang [email protected] Signed-off-by: clairewangosrf <[email protected]> Signed-off-by: claireyywang <[email protected]> * update code format Signed-off-by: clairewangosrf <[email protected]> Signed-off-by: claireyywang <[email protected]> * added rosdistro Signed-off-by: clairewangosrf <[email protected]> Signed-off-by: claireyywang <[email protected]> * fixed style and added rosdistro Signed-off-by: claireyywang <[email protected]> * fixed code style Signed-off-by: claireyywang <[email protected]> * corrected code style Signed-off-by: claireyywang <[email protected]> * added network interface print command Signed-off-by: claireyywang <[email protected]> * leave out network verb, change cmd name to doctor, add alias wtf Signed-off-by: claireyywang <[email protected]> * remove network.py Signed-off-by: claireyywang <[email protected]> * add version, rosdistro, platformdist, fallback checks, fallback checks Signed-off-by: claireyywang <[email protected]> * add wtf alias, separate checks and report Signed-off-by: claireyywang <[email protected]> * remove duplicates, correct grammer Signed-off-by: claireyywang <[email protected]> * add entrypoints for checks and report, output failed checks Signed-off-by: claireyywang <[email protected]> * corrected code format Signed-off-by: claireyywang <[email protected]> * reformat report, correct typo Signed-off-by: claireyywang <[email protected]>
1 parent 55f4830 commit 3ff2adb

File tree

11 files changed

+334
-0
lines changed

11 files changed

+334
-0
lines changed

ros2doctor/package.xml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0"?>
2+
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
3+
<package format="3">
4+
<name>ros2doctor</name>
5+
<version>0.7.4</version>
6+
<description>A command line tool to check potential issues in a ROS 2 system</description>
7+
<maintainer email="[email protected]">Claire Wang</maintainer>
8+
<license>Apache License 2.0</license>
9+
10+
<depend>ros2cli</depend>
11+
12+
<exec_depend>python3-numpy</exec_depend>
13+
<exec_depend>python3-rosdistro-modules</exec_depend>
14+
15+
<test_depend>ament_copyright</test_depend>
16+
<test_depend>ament_flake8</test_depend>
17+
<test_depend>ament_pep257</test_depend>
18+
<test_depend>ament_xmllint</test_depend>
19+
<test_depend>python3-pytest</test_depend>
20+
21+
<export>
22+
<build_type>ament_python</build_type>
23+
</export>
24+
</package>

ros2doctor/ros2doctor/__init__.py

Whitespace-only changes.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright 2019 Open Source Robotics Foundation, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from pkg_resources import iter_entry_points
16+
17+
18+
def run_checks():
19+
"""Run all checks when `ros2 doctor/wtf` is called."""
20+
all_results = []
21+
failed_names = []
22+
for check in iter_entry_points('ros2doctor.checks'):
23+
result = check.load()() # load() returns method
24+
all_results.append(result)
25+
if result is False:
26+
failed_names.append(check.name)
27+
return all_results, failed_names
28+
29+
30+
def generate_report():
31+
"""Print report to terminal when `-r/--report` is attached."""
32+
for report in iter_entry_points('ros2doctor.report'):
33+
report.load()() # load() returns method
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
# Copyright 2019 Open Source Robotics Foundation, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import os
16+
import platform
17+
import sys
18+
19+
import rosdistro
20+
21+
22+
def print_platform_info():
23+
"""Print out platform information."""
24+
platform_name = platform.system()
25+
# platform info
26+
print('PLATFORM INFORMATION')
27+
print('system : ', platform_name)
28+
print('Platform Info : ', platform.platform())
29+
if platform_name == 'Darwin':
30+
print('Mac OS version : ', platform.mac_ver())
31+
print('release : ', platform.release())
32+
print('processor : ', platform.processor())
33+
34+
# python info
35+
print('PYTHON INFORMATION')
36+
print('version : ', platform.python_version())
37+
print('compiler : ', platform.python_compiler())
38+
print('build : ', platform.python_build())
39+
40+
41+
def check_platform_helper():
42+
"""Check ROS_DISTRO related environment variables and distribution name."""
43+
distro_name = os.environ.get('ROS_DISTRO')
44+
if not distro_name:
45+
sys.stderr.write('WARNING: ROS_DISTRO is not set.')
46+
return
47+
else:
48+
distro_name = distro_name.lower()
49+
u = rosdistro.get_index_url()
50+
if not u:
51+
sys.stderr.write('WARNING: Unable to access ROSDISTRO_INDEX_URL\
52+
or DEFAULT_INDEX_URL.')
53+
return
54+
i = rosdistro.get_index(u)
55+
distro_info = i.distributions.get(distro_name)
56+
if not distro_info:
57+
sys.stderr.write("WARNING: Distribution name '%s' is not found" % distro_name)
58+
return
59+
distro_data = rosdistro.get_distribution(i, distro_name).get_data()
60+
return distro_name, distro_info, distro_data
61+
62+
63+
def print_ros2_info():
64+
"""Print out ROS2 distribution info using `rosdistro`."""
65+
distros = check_platform_helper()
66+
if not distros:
67+
return
68+
distro_name, distro_info, distro_data = distros
69+
70+
print('ROS INFORMATION')
71+
print('distribution name : ', distro_name)
72+
print('distribution type : ', distro_info.get('distribution_type'))
73+
print('distribution status : ', distro_info.get('distribution_status'))
74+
print('release platforms : ', distro_data.get('release_platforms'))
75+
76+
77+
def check_platform():
78+
"""Check platform information against ROS 2 requirements."""
79+
passed = False
80+
distros = check_platform_helper()
81+
if not distros:
82+
return passed
83+
_, distro_info, _ = distros
84+
85+
# check distro status
86+
if distro_info.get('distribution_status') == 'prerelease':
87+
sys.stderr.write('WARNING: Distribution is not fully supported or tested.\
88+
To get more stable features,\
89+
Download a stable version at\
90+
https://index.ros.org/doc/ros2/Installation/')
91+
elif distro_info.get('distribution_status') == 'end-of-life':
92+
sys.stderr.write('WARNING: Distribution is no longer supported or deprecated.\
93+
To get the latest features,\
94+
Download the latest version at\
95+
https://index.ros.org/doc/ros2/Installation/')
96+
else:
97+
passed = True
98+
return passed

ros2doctor/ros2doctor/command/__init__.py

Whitespace-only changes.
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Copyright 2019 Open Source Robotics Foundation, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from ros2cli.command import CommandExtension
16+
from ros2doctor.api import generate_report
17+
from ros2doctor.api import run_checks
18+
19+
20+
class DoctorCommand(CommandExtension):
21+
"""Check ROS setup and other potential issues."""
22+
23+
def add_arguments(self, parser, cli_name):
24+
parser.add_argument(
25+
'--report', '-r', action='store_true',
26+
help='Print out doctor report.'
27+
)
28+
29+
def main(self, *, parser, args):
30+
if args.report:
31+
generate_report()
32+
else:
33+
all_result, failed_names = run_checks()
34+
failed = all_result.count(False)
35+
passed = all_result.count(True)
36+
if failed != 0:
37+
print('%d/%d checks failed' % (failed, len(all_result)))
38+
print('Failed checks:', *failed_names)
39+
else:
40+
print('%d/%d checks passed' % (passed, len(all_result)))
41+
42+
43+
class WtfCommand(DoctorCommand):
44+
"""Add `wtf` as alias to `doctor`."""
45+
46+
pass

ros2doctor/setup.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from setuptools import find_packages
2+
from setuptools import setup
3+
4+
setup(
5+
name='ros2doctor',
6+
version='0.7.4',
7+
packages=find_packages(exclude=['test']),
8+
install_requires=['ros2cli'],
9+
zip_safe=True,
10+
author='Claire Wang',
11+
author_email='[email protected]',
12+
maintainer='Claire Wang',
13+
maintainer_email='[email protected]',
14+
url='',
15+
download_url='',
16+
keywords=[],
17+
classifiers=[
18+
'Environment :: Console',
19+
'Intended Audience :: Developers',
20+
'License :: OSI Approved :: Apache Software License',
21+
'Programming Language :: Python',
22+
],
23+
description='The doctor command for ROS 2 command line tools',
24+
long_description="""\
25+
The package provides a cli tool to check potential issues in a ROS 2 system""",
26+
license='Apache License, Version 2.0',
27+
tests_require=['pytest'],
28+
entry_points={
29+
'ros2cli.command': [
30+
'doctor = ros2doctor.command.doctor:DoctorCommand',
31+
'wtf = ros2doctor.command.doctor:WtfCommand',
32+
],
33+
'ros2doctor.checks': [
34+
'check_platform = ros2doctor.api.platform:check_platform',
35+
],
36+
'ros2doctor.report': [
37+
'report_platform = ros2doctor.api.platform:print_platform_info',
38+
'report_ros_distro = ros2doctor.api.platform:print_ros2_info',
39+
],
40+
}
41+
)

ros2doctor/test/test_copyright.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright 2019 Open Source Robotics Foundation, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from ament_copyright.main import main
16+
import pytest
17+
18+
19+
@pytest.mark.copyright
20+
@pytest.mark.linter
21+
def test_copyright():
22+
rc = main(argv=['.', 'test'])
23+
assert rc == 0, 'Found errors'

ros2doctor/test/test_flake8.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright 2019 Open Source Robotics Foundation, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from ament_flake8.main import main
16+
import pytest
17+
18+
19+
@pytest.mark.flake8
20+
@pytest.mark.linter
21+
def test_flake8():
22+
rc = main(argv=[])
23+
assert rc == 0, 'Found errors'

ros2doctor/test/test_pep257.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright 2019 Open Source Robotics Foundation, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from ament_pep257.main import main
16+
import pytest
17+
18+
19+
@pytest.mark.linter
20+
@pytest.mark.pep257
21+
def test_pep257():
22+
rc = main(argv=[])
23+
assert rc == 0, 'Found code style errors / warnings'

0 commit comments

Comments
 (0)