Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set up code checks #25

Merged
merged 5 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
Language: Cpp
BasedOnStyle: Google
ColumnLimit: 120
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Add git commit hashes to ignore for blame
0da6a5e499812b03d4135ff32a9b1ab01bd07ed9
16 changes: 16 additions & 0 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Code style checks

on:
pull_request:
push:
branches: [main]

jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- name: Install cppcheck
run: sudo apt install cppcheck -y
- uses: pre-commit/[email protected]
23 changes: 23 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.277
hooks:
- id: ruff
args:
- "--fix"
- "--exit-non-zero-on-fix"
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
- repo: https://github.com/pocc/pre-commit-hooks
rev: v1.3.5
hooks:
- id: clang-format
args:
- "-i"
- id: cppcheck
args:
- "--suppress=missingInclude"
- "--suppress=unmatchedSuppression"
- "--suppress=unusedFunction"
71 changes: 32 additions & 39 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
#
# Full list of options at http://www.sphinx-doc.org/en/master/config

# -- Path setup --------------------------------------------------------------
Expand All @@ -10,18 +8,20 @@
#
import os
import sys
import catkin_pkg.package

import catkin_pkg.package
from exhale import utils

package_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
catkin_package = catkin_pkg.package.parse_package(
os.path.join(package_dir, catkin_pkg.package.PACKAGE_MANIFEST_FILENAME))
os.path.join(package_dir, catkin_pkg.package.PACKAGE_MANIFEST_FILENAME)
)
sys.path.insert(0, os.path.abspath(os.path.join(package_dir, "src")))


# -- Helper functions --------------------------------------------------------


def count_files():
""":returns tuple of (num_py, num_cpp)"""
num_py = 0
Expand All @@ -42,7 +42,7 @@ def count_files():
# -- Project information -----------------------------------------------------

project = catkin_package.name
copyright = '2019, Bit-Bots'
copyright = "2019, Bit-Bots"
author = ", ".join([a.name for a in catkin_package.authors])

# The short X.Y version
Expand All @@ -60,27 +60,27 @@ def count_files():
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.coverage',
'sphinx.ext.imgmath',
'sphinx.ext.viewcode',
'sphinx_rtd_theme',
"sphinx.ext.autodoc",
"sphinx.ext.doctest",
"sphinx.ext.intersphinx",
"sphinx.ext.todo",
"sphinx.ext.coverage",
"sphinx.ext.imgmath",
"sphinx.ext.viewcode",
"sphinx_rtd_theme",
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ["_templates"]

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
source_suffix = ".rst"

# The master toctree document.
master_doc = 'index'
master_doc = "index"

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand All @@ -92,7 +92,7 @@ def count_files():
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = None
Expand All @@ -108,24 +108,17 @@ def count_files():

if num_files_cpp > 0:
extensions += [
'breathe',
'exhale',
"breathe",
"exhale",
]

breathe_projects = {
project: os.path.join("_build", "doxyoutput", "xml")
}
breathe_projects = {project: os.path.join("_build", "doxyoutput", "xml")}
breathe_default_project = project

def specifications_for_kind(kind):
# Show all members for classes and structs
if kind == "class" or kind == "struct":
return [
":members:",
":protected-members:",
":private-members:",
":undoc-members:"
]
return [":members:", ":protected-members:", ":private-members:", ":undoc-members:"]
# An empty list signals to Exhale to use the defaults
else:
return []
Expand All @@ -136,21 +129,19 @@ def specifications_for_kind(kind):
"rootFileName": "library_root.rst",
"rootFileTitle": "C++ Library API",
"doxygenStripFromPath": "..",
"customSpecificationsMapping": utils.makeCustomSpecificationsMapping(
specifications_for_kind
),
"customSpecificationsMapping": utils.makeCustomSpecificationsMapping(specifications_for_kind),
# Suggested optional arguments
"createTreeView": True,
"exhaleExecutesDoxygen": True,
"exhaleDoxygenStdin": "INPUT = {}".format(os.path.join(package_dir, "include"))
"exhaleDoxygenStdin": "INPUT = {}".format(os.path.join(package_dir, "include")),
}

# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'sphinx_rtd_theme'
html_theme = "sphinx_rtd_theme"

# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
Expand All @@ -161,7 +152,7 @@ def specifications_for_kind(kind):
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
html_static_path = ["_static"]

# Custom sidebar templates, must be a dictionary that maps document names
# to template names.
Expand All @@ -173,21 +164,23 @@ def specifications_for_kind(kind):
#
# html_sidebars = {}

html_logo = os.path.join('_static', 'logo.png')
html_favicon = os.path.join('_static', 'logo.png')
html_logo = os.path.join("_static", "logo.png")
html_favicon = os.path.join("_static", "logo.png")


# -- Options for intersphinx extension ---------------------------------------

# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'https://docs.python.org/': None}
intersphinx_mapping = {"https://docs.python.org/": None}

# -- Options for todo extension ----------------------------------------------

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True

# -- RST Standard variables ---------------------------------------------------
rst_prolog = ".. |project| replace:: {}\n".format(project)
rst_prolog = f".. |project| replace:: {project}\n"
rst_prolog += ".. |description| replace:: {}\n".format(catkin_package.description.replace("\n\n", "\n"))
rst_prolog += ".. |modindex| replace:: {}\n".format(":ref:`modindex`" if num_files_py > 0 else "Python module index is not available")
rst_prolog += ".. |modindex| replace:: {}\n".format(
":ref:`modindex`" if num_files_py > 0 else "Python module index is not available"
)
6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[tool.black]
line-length = 120

[tool.ruff]
line-length = 120
select = ["F", "E", "W", "I", "N", "UP"]
48 changes: 23 additions & 25 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,29 @@
import glob

from setuptools import find_packages
from setuptools import setup
from setuptools import find_packages, setup

package_name = 'udp_bridge'
package_name = "udp_bridge"

setup(
name=package_name,
packages=find_packages(exclude=['test']),
data_files=[
('share/ament_index/resource_index/packages',
['resource/' + package_name]),
('share/' + package_name, ['package.xml']),
('share/' + package_name + '/config', glob.glob('config/*.yaml')),
('share/' + package_name + '/launch', glob.glob('launch/*.launch')),
],
install_requires=[
'launch',
'setuptools',
],
zip_safe=True,
keywords=['ROS'],
license='MIT',
entry_points={
'console_scripts': [
f'receiver = {package_name}.receiver:main',
f'sender = {package_name}.sender:main',
],
}
name=package_name,
packages=find_packages(exclude=["test"]),
data_files=[
("share/ament_index/resource_index/packages", ["resource/" + package_name]),
("share/" + package_name, ["package.xml"]),
("share/" + package_name + "/config", glob.glob("config/*.yaml")),
("share/" + package_name + "/launch", glob.glob("launch/*.launch")),
],
install_requires=[
"launch",
"setuptools",
],
zip_safe=True,
keywords=["ROS"],
license="MIT",
entry_points={
"console_scripts": [
f"receiver = {package_name}.receiver:main",
f"sender = {package_name}.sender:main",
],
},
)
6 changes: 4 additions & 2 deletions test/rostests/test_sender.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#!/usr/bin/env python3
import rospy
import socket
from std_msgs import msg

import rospy
from bitbots_test.test_case import RosNodeTestCase
from std_msgs import msg


class SenderTestCase(RosNodeTestCase):
Expand All @@ -24,4 +25,5 @@ def test_topic_gets_published_and_sent(self):

if __name__ == "__main__":
from bitbots_test import run_rostests

run_rostests(SenderTestCase)
8 changes: 5 additions & 3 deletions test/rostests/test_sender_receiver.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#!/usr/bin/env python3
import rospy
from socket import gethostname
from std_msgs import msg
from bitbots_test.test_case import RosNodeTestCase

import rospy
from bitbots_test.mocks import MockSubscriber
from bitbots_test.test_case import RosNodeTestCase
from std_msgs import msg


class SenderReceiverTestCase(RosNodeTestCase):
Expand All @@ -23,4 +24,5 @@ def test_sent_message_gets_received_over_bridge(self):

if __name__ == "__main__":
from bitbots_test import run_rostests

run_rostests(SenderReceiverTestCase)
10 changes: 6 additions & 4 deletions test/unit_tests/test_aes_helper.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
from udp_bridge import aes_helper
from hypothesis import given, assume
from hypothesis.strategies import text
from bitbots_test.test_case import TestCase
from hypothesis import assume, given
from hypothesis.strategies import text

from udp_bridge import aes_helper


class AesHelperTestCase(TestCase):
Expand All @@ -15,6 +16,7 @@ def test_decrypt_inverts_encrypt(self, message, key):
self.assertEqual(message, dec_text)


if __name__ == '__main__':
if __name__ == "__main__":
from bitbots_test import run_unit_tests

run_unit_tests(AesHelperTestCase)
3 changes: 1 addition & 2 deletions udp_bridge/aes_helper.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import base64
from typing import Optional

from cryptography.fernet import Fernet
from cryptography.hazmat.backends import default_backend
Expand All @@ -15,7 +14,7 @@ class AESCipher:
It is safe to keep one object because the internal python cipher is not reused.
"""

def __init__(self, key: Optional[str]):
def __init__(self, key: str | None):
"""
:param key: The passphrase used to encrypt and decrypt messages.
If it is None, no encryption/decryption takes place
Expand Down
3 changes: 1 addition & 2 deletions udp_bridge/message_handler.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import base64
import pickle

from typing import Optional
from udp_bridge.aes_helper import AESCipher


class MessageHandler:
PACKAGE_DELIMITER = b"\xff\xff\xff"

def __init__(self, encryption_key: Optional[str]):
def __init__(self, encryption_key: str | None):
self.cipher = AESCipher(encryption_key)

def encrypt_and_encode(self, data: dict) -> bytes:
Expand Down
Loading