diff --git a/.github/workflows/debian-packages.yml b/.github/workflows/debian-packages.yml index 77e948c..da25bd7 100644 --- a/.github/workflows/debian-packages.yml +++ b/.github/workflows/debian-packages.yml @@ -1,5 +1,5 @@ # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -318,4 +318,4 @@ jobs: sleep 2 kill -9 $(cat /tmp/gwm.pid) 2>/dev/null || true ros2 daemon stop || true - shell: bash \ No newline at end of file + shell: bash diff --git a/.github/workflows/ros-tests.yml b/.github/workflows/ros-tests.yml index b2e4d5e..ed11dcd 100644 --- a/.github/workflows/ros-tests.yml +++ b/.github/workflows/ros-tests.yml @@ -1,5 +1,5 @@ # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -27,6 +27,17 @@ env: ROS_AUTOMATIC_DISCOVERY_RANGE: LOCALHOST jobs: + pre-commit: + name: Pre-commit checks (linting, copyright check, etc.) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y uncrustify git + - uses: pre-commit/action@v3.0.1 + test: name: Test ROS2 ${{ matrix.ros_distro }} runs-on: ubuntu-latest @@ -138,4 +149,4 @@ jobs: with: name: test-results-${{ matrix.ros_distro }} path: build/*/test_results/**/*.xml - retention-days: 7 \ No newline at end of file + retention-days: 7 diff --git a/.gitignore b/.gitignore index 5b49528..803c0d1 100644 --- a/.gitignore +++ b/.gitignore @@ -89,4 +89,4 @@ _deps # Temporary files *.tmp -*.temp \ No newline at end of file +*.temp diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..aa2eafb --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +exclude: ^(build|install)/ +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 + hooks: + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace +- repo: https://github.com/hhatto/autopep8 + rev: v2.3.1 + hooks: + - id: autopep8 + args: [--max-line-length=99, -i] +- repo: https://github.com/pycqa/flake8 + rev: 7.1.1 + hooks: + - id: flake8 + args: [--max-line-length=99, '--extend-ignore=B902,C816,D100,D101,D102,D103,D104,D105,D106,D107,D203,D212,D404,I202'] +- repo: https://github.com/scop/pre-commit-shfmt + rev: v3.12.0-2 + hooks: + - id: shfmt +- repo: https://github.com/sbrunner/hooks + rev: 1.6.1 + hooks: + - id: copyright-required + exclude: '(^\.git/|(\.ini|\.json|\.service|__init__\.py|\.md|\.gitkeep|\.conf|LICENSE|\.toml|\.template|\.style\..*|\.gitattributes|\.gitignore|\.editorconfig|\.bash-completion|\.install|\.links|changelog|debian/source/format|.codespellrc|copyright|ament_code_style\.cfg|test_pep257\.py|test_flake8\.py|test_copyright\.py)$)' +- repo: local + hooks: + - id: uncrustify + name: uncrustify + entry: uncrustify -c ament_code_style.cfg --replace --no-backup + language: system + types_or: [c, c++] + - id: signed-off-by + name: check commit is signed off + entry: "bash -c 'grep -q \"^Signed-off-by: \" \"$1\"' --" + language: system + stages: [commit-msg] + pass_filenames: true +- repo: https://github.com/codespell-project/codespell + rev: v2.4.1 + hooks: + - id: codespell diff --git a/Contributing.md b/Contributing.md index dde649a..fb9f42f 100644 --- a/Contributing.md +++ b/Contributing.md @@ -1,4 +1,8 @@ -We welcome PRs for new features or bugfixes, CI will automatically run automated tests on new PRs. You can also use the scripts/docker-test.sh to debug tests for a particular distribution locally. +# Contributing + +We welcome PRs for new features or bugfixes, CI will automatically run automated tests on new PRs. You can also use the scripts/docker-test.sh to debug tests for a particular distribution locally. + +## Sign Off We require that all contributors "sign-off" on their commits. This certifies that the contribution is your original work, or you have rights to submit it under the same license, or a compatible license. @@ -52,3 +56,22 @@ By making a contribution to this project, I certify that: maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. ``` + +## Pre-commit hooks (linting, sign-off check, copyright check, etc.) + +If you would like the linter and other checks to run on every commit use [pre-commit](https://pre-commit.com/): + +``` +sudo apt install uncrustify pipx +pipx install pre-commit +pre-commit install --hook-type pre-commit --hook-type commit-msg +pre-commit run --all-files # try it out, this will run every commit now +``` + +On every commit now a series of checks will be run to ensure the changes are meeting this repositories requirements. + +Uninstall pre-commit with: + +``` +pre-commit uninstall --hook-type pre-commit --hook-type commit-msg +``` diff --git a/README.md b/README.md index c926a89..b4011f2 100644 --- a/README.md +++ b/README.md @@ -109,4 +109,4 @@ If you want to use it as a command line tool, you can do so with the following l ```bash ros2 launch greenwave_monitor hz.launch.py gw_monitored_topics:='["/topic1", "/topic2"]' -``` \ No newline at end of file +``` diff --git a/greenwave_monitor/CMakeLists.txt b/greenwave_monitor/CMakeLists.txt index e28c566..9135e8d 100644 --- a/greenwave_monitor/CMakeLists.txt +++ b/greenwave_monitor/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/examples/README.md b/greenwave_monitor/examples/README.md index cfa4518..15651c2 100644 --- a/greenwave_monitor/examples/README.md +++ b/greenwave_monitor/examples/README.md @@ -31,4 +31,4 @@ Node( ), ``` -To see the output with the r2s_gw dashboard, run `ros2 run r2s_gw r2s_gw` in a separate terminal. \ No newline at end of file +To see the output with the r2s_gw dashboard, run `ros2 run r2s_gw r2s_gw` in a separate terminal. diff --git a/greenwave_monitor/greenwave_monitor/ncurses_frontend.py b/greenwave_monitor/greenwave_monitor/ncurses_frontend.py index a50d231..0f3359f 100644 --- a/greenwave_monitor/greenwave_monitor/ncurses_frontend.py +++ b/greenwave_monitor/greenwave_monitor/ncurses_frontend.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/greenwave_monitor/test_utils.py b/greenwave_monitor/greenwave_monitor/test_utils.py index 49f5e0d..e952720 100644 --- a/greenwave_monitor/greenwave_monitor/test_utils.py +++ b/greenwave_monitor/greenwave_monitor/test_utils.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -176,7 +176,7 @@ def find_best_diagnostic( diagnostics: List[DiagnosticStatus], expected_frequency: float, message_type: str - ) -> Tuple[Optional[DiagnosticStatus], Optional[Tuple[float, float, float]]]: +) -> Tuple[Optional[DiagnosticStatus], Optional[Tuple[float, float, float]]]: """Find the diagnostic message with frequency closest to expected.""" best_status = None best_values = None diff --git a/greenwave_monitor/greenwave_monitor/ui_adaptor.py b/greenwave_monitor/greenwave_monitor/ui_adaptor.py index 30d84ba..015962b 100644 --- a/greenwave_monitor/greenwave_monitor/ui_adaptor.py +++ b/greenwave_monitor/greenwave_monitor/ui_adaptor.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/include/greenwave_diagnostics.hpp b/greenwave_monitor/include/greenwave_diagnostics.hpp index 42ccafe..b291d73 100644 --- a/greenwave_monitor/include/greenwave_diagnostics.hpp +++ b/greenwave_monitor/include/greenwave_diagnostics.hpp @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -// Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/include/greenwave_monitor.hpp b/greenwave_monitor/include/greenwave_monitor.hpp index fdb1e0a..d6368c9 100644 --- a/greenwave_monitor/include/greenwave_monitor.hpp +++ b/greenwave_monitor/include/greenwave_monitor.hpp @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -// Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/include/minimal_publisher_node.hpp b/greenwave_monitor/include/minimal_publisher_node.hpp index f1fcbb3..8691946 100644 --- a/greenwave_monitor/include/minimal_publisher_node.hpp +++ b/greenwave_monitor/include/minimal_publisher_node.hpp @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -// Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/launch/hz.launch.py b/greenwave_monitor/launch/hz.launch.py index bb679df..534d040 100644 --- a/greenwave_monitor/launch/hz.launch.py +++ b/greenwave_monitor/launch/hz.launch.py @@ -1,4 +1,4 @@ -# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/launch/test_publishers.launch.py b/greenwave_monitor/launch/test_publishers.launch.py index e1907c9..728e5a0 100644 --- a/greenwave_monitor/launch/test_publishers.launch.py +++ b/greenwave_monitor/launch/test_publishers.launch.py @@ -1,4 +1,4 @@ -# Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/scripts/ncurses_dashboard b/greenwave_monitor/scripts/ncurses_dashboard index 807a777..b75d2d1 100755 --- a/greenwave_monitor/scripts/ncurses_dashboard +++ b/greenwave_monitor/scripts/ncurses_dashboard @@ -1,7 +1,7 @@ #!/bin/bash # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -27,77 +27,77 @@ HIDE_UNMONITORED=false MONITOR_ARGS=() show_help() { - echo "Usage: $0 [OPTIONS] [MONITOR_ARGS...]" - echo "" - echo "Launch Greenwave Monitor with ncurses TUI dashboard" - echo "" - echo "OPTIONS:" - echo " --demo, --test Launch demo publisher nodes for testing" - echo " --log-dir DIR Enable logging to specified directory" - echo " --hide-unmonitored Hide unmonitored topics on initialization" - echo " --help, -h Show this help message" - echo "" - echo "MONITOR_ARGS are passed directly to the greenwave_monitor node" - echo "" - echo "Controls in ncurses interface:" - echo " enter/space = toggle topic monitoring" - echo " f = Set expected frequency for selected topic (format: hz tolerance%)" - echo " c = Clear frequency settings for selected topic" - echo " h = Toggle hiding unmonitored topics" - echo " ↑/↓ = Navigate topics" - echo " q = Quit" + echo "Usage: $0 [OPTIONS] [MONITOR_ARGS...]" + echo "" + echo "Launch Greenwave Monitor with ncurses TUI dashboard" + echo "" + echo "OPTIONS:" + echo " --demo, --test Launch demo publisher nodes for testing" + echo " --log-dir DIR Enable logging to specified directory" + echo " --hide-unmonitored Hide unmonitored topics on initialization" + echo " --help, -h Show this help message" + echo "" + echo "MONITOR_ARGS are passed directly to the greenwave_monitor node" + echo "" + echo "Controls in ncurses interface:" + echo " enter/space = toggle topic monitoring" + echo " f = Set expected frequency for selected topic (format: hz tolerance%)" + echo " c = Clear frequency settings for selected topic" + echo " h = Toggle hiding unmonitored topics" + echo " ↑/↓ = Navigate topics" + echo " q = Quit" } while [[ $# -gt 0 ]]; do - case $1 in - --demo|--test) - DEMO_MODE=true - shift - ;; - --log-dir) - LOG_DIR="$2" - shift 2 - ;; - --hide-unmonitored) - HIDE_UNMONITORED=true - shift - ;; - --help|-h) - show_help - exit 0 - ;; - *) - MONITOR_ARGS+=("$1") - shift - ;; - esac + case $1 in + --demo | --test) + DEMO_MODE=true + shift + ;; + --log-dir) + LOG_DIR="$2" + shift 2 + ;; + --hide-unmonitored) + HIDE_UNMONITORED=true + shift + ;; + --help | -h) + show_help + exit 0 + ;; + *) + MONITOR_ARGS+=("$1") + shift + ;; + esac done # Handle logging configuration LOG_FILE="/dev/null" if [ -n "$LOG_DIR" ]; then - # Create logs directory if it doesn't exist - mkdir -p "${LOG_DIR}" + # Create logs directory if it doesn't exist + mkdir -p "${LOG_DIR}" - # Create a timestamped log file - TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S") - LOG_FILE="${LOG_DIR}/monitor_ncurses_${TIMESTAMP}.log" + # Create a timestamped log file + TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S") + LOG_FILE="${LOG_DIR}/monitor_ncurses_${TIMESTAMP}.log" fi # Function to clean up background processes on exit cleanup() { - echo "Shutting down..." - if [ -n "$MONITOR_PID" ]; then - echo "Terminating monitor node (PID: $MONITOR_PID)..." - if [ "$LOG_FILE" != "/dev/null" ]; then - echo "Monitor log available at: ${LOG_FILE}" - fi - # Kill background process and all its descendants - pkill -TERM -P $MONITOR_PID 2>/dev/null - kill -TERM $MONITOR_PID 2>/dev/null - fi - exit 0 + echo "Shutting down..." + if [ -n "$MONITOR_PID" ]; then + echo "Terminating monitor node (PID: $MONITOR_PID)..." + if [ "$LOG_FILE" != "/dev/null" ]; then + echo "Monitor log available at: ${LOG_FILE}" + fi + # Kill background process and all its descendants + pkill -TERM -P $MONITOR_PID 2>/dev/null + kill -TERM $MONITOR_PID 2>/dev/null + fi + exit 0 } # Set up trap to catch signals @@ -105,13 +105,13 @@ trap cleanup SIGINT SIGTERM EXIT # Launch demo nodes if requested if [ "$DEMO_MODE" = "true" ]; then - echo "Starting demo mode with test publisher nodes..." - ros2 launch greenwave_monitor example.launch.py &> "${LOG_FILE}" & - MONITOR_PID=$! + echo "Starting demo mode with test publisher nodes..." + ros2 launch greenwave_monitor example.launch.py &>"${LOG_FILE}" & + MONITOR_PID=$! else - echo "Starting Greenwave Monitor..." - ros2 run greenwave_monitor greenwave_monitor "${MONITOR_ARGS[@]}" &> "${LOG_FILE}" & - MONITOR_PID=$! + echo "Starting Greenwave Monitor..." + ros2 run greenwave_monitor greenwave_monitor "${MONITOR_ARGS[@]}" &>"${LOG_FILE}" & + MONITOR_PID=$! fi # Wait briefly to allow the monitor node to initialize @@ -124,7 +124,7 @@ echo "Controls: a=Add Topic, r=Remove, f=Set Frequency, c=Clear Freq, q=Quit" # NOTE: add proper argument parsing to the ncurses frontend if more than one argument is added here FRONTEND_ARGS=() if [ "$HIDE_UNMONITORED" = "true" ]; then - FRONTEND_ARGS+=("--hide-unmonitored") + FRONTEND_ARGS+=("--hide-unmonitored") fi python3 -m greenwave_monitor.ncurses_frontend "${FRONTEND_ARGS[@]}" diff --git a/greenwave_monitor/src/greenwave_monitor.cpp b/greenwave_monitor/src/greenwave_monitor.cpp index 9d59ff4..3736b51 100644 --- a/greenwave_monitor/src/greenwave_monitor.cpp +++ b/greenwave_monitor/src/greenwave_monitor.cpp @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -// Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/src/greenwave_monitor_main.cpp b/greenwave_monitor/src/greenwave_monitor_main.cpp index 95fc005..edf9aa1 100644 --- a/greenwave_monitor/src/greenwave_monitor_main.cpp +++ b/greenwave_monitor/src/greenwave_monitor_main.cpp @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -// Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/src/minimal_publisher_node.cpp b/greenwave_monitor/src/minimal_publisher_node.cpp index 0258b06..88b695b 100644 --- a/greenwave_monitor/src/minimal_publisher_node.cpp +++ b/greenwave_monitor/src/minimal_publisher_node.cpp @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -// Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/test/test_greenwave_diagnostics.cpp b/greenwave_monitor/test/test_greenwave_diagnostics.cpp index 6b158ae..c201049 100644 --- a/greenwave_monitor/test/test_greenwave_diagnostics.cpp +++ b/greenwave_monitor/test/test_greenwave_diagnostics.cpp @@ -1,5 +1,5 @@ // SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -// Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/test/test_greenwave_monitor.py b/greenwave_monitor/test/test_greenwave_monitor.py index 82b58d4..4fd10c4 100644 --- a/greenwave_monitor/test/test_greenwave_monitor.py +++ b/greenwave_monitor/test/test_greenwave_monitor.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/test/test_ncurses_frontend_argparse.py b/greenwave_monitor/test/test_ncurses_frontend_argparse.py index a12f8f3..db6e500 100644 --- a/greenwave_monitor/test/test_ncurses_frontend_argparse.py +++ b/greenwave_monitor/test/test_ncurses_frontend_argparse.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/greenwave_monitor/test/test_topic_monitoring_integration.py b/greenwave_monitor/test/test_topic_monitoring_integration.py index 3641c64..5f93769 100644 --- a/greenwave_monitor/test/test_topic_monitoring_integration.py +++ b/greenwave_monitor/test/test_topic_monitoring_integration.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2024-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/greenwave_monitor_interfaces/CMakeLists.txt b/greenwave_monitor_interfaces/CMakeLists.txt index a3c2b46..68b3691 100644 --- a/greenwave_monitor_interfaces/CMakeLists.txt +++ b/greenwave_monitor_interfaces/CMakeLists.txt @@ -1,5 +1,5 @@ # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -30,4 +30,4 @@ rosidl_generate_interfaces(${PROJECT_NAME} "srv/SetExpectedFrequency.srv" ) -ament_package() \ No newline at end of file +ament_package() diff --git a/greenwave_monitor_interfaces/package.xml b/greenwave_monitor_interfaces/package.xml index 8e9e6ee..011eb9b 100644 --- a/greenwave_monitor_interfaces/package.xml +++ b/greenwave_monitor_interfaces/package.xml @@ -1,4 +1,23 @@ + + + greenwave_monitor_interfaces diff --git a/greenwave_monitor_interfaces/srv/ManageTopic.srv b/greenwave_monitor_interfaces/srv/ManageTopic.srv index ae8abb1..8a7b637 100644 --- a/greenwave_monitor_interfaces/srv/ManageTopic.srv +++ b/greenwave_monitor_interfaces/srv/ManageTopic.srv @@ -1,5 +1,5 @@ # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,4 +21,4 @@ bool add_topic # true to add, false to remove --- # Response bool success -string message \ No newline at end of file +string message diff --git a/greenwave_monitor_interfaces/srv/SetExpectedFrequency.srv b/greenwave_monitor_interfaces/srv/SetExpectedFrequency.srv index cf61ff4..e4bfba6 100644 --- a/greenwave_monitor_interfaces/srv/SetExpectedFrequency.srv +++ b/greenwave_monitor_interfaces/srv/SetExpectedFrequency.srv @@ -1,5 +1,5 @@ # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,4 +24,4 @@ bool add_topic_if_missing # add topic to monitoring if not already --- # Response bool success -string message \ No newline at end of file +string message diff --git a/scripts/build_debian_packages.sh b/scripts/build_debian_packages.sh index 8e7f8be..4f011af 100755 --- a/scripts/build_debian_packages.sh +++ b/scripts/build_debian_packages.sh @@ -1,7 +1,7 @@ #!/bin/bash # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -49,55 +49,53 @@ UBUNTU_DISTRO="${2:-$DEFAULT_UBUNTU_DISTRO}" # Validate ROS distro case "$ROS_DISTRO" in - humble|iron|jazzy|kilted|rolling) - ;; - *) - echo "Error: Unsupported ROS distro: $ROS_DISTRO" - echo "Supported distros: humble, iron, jazzy, kilted, rolling" - exit 1 - ;; +humble | iron | jazzy | kilted | rolling) ;; +*) + echo "Error: Unsupported ROS distro: $ROS_DISTRO" + echo "Supported distros: humble, iron, jazzy, kilted, rolling" + exit 1 + ;; esac # Validate Ubuntu distro case "$UBUNTU_DISTRO" in - jammy|noble) - ;; - *) - echo "Error: Unsupported Ubuntu distro: $UBUNTU_DISTRO" - echo "Supported distros: jammy, noble" - exit 1 - ;; +jammy | noble) ;; +*) + echo "Error: Unsupported Ubuntu distro: $UBUNTU_DISTRO" + echo "Supported distros: jammy, noble" + exit 1 + ;; esac echo "Building Debian packages for ROS $ROS_DISTRO on Ubuntu $UBUNTU_DISTRO" # Check if running in a container (recommended) or warn user if [ ! -f "/.dockerenv" ] && [ ! -f "/run/.containerenv" ]; then - echo "WARNING: Not running in a container. This script is designed to run in a clean Ubuntu container." - echo "" - echo "Recommended: Run in Docker with:" - echo " docker run -it --rm -v \$(pwd):/workspace -w /workspace ubuntu:$UBUNTU_DISTRO ./scripts/build_debian_packages.sh $ROS_DISTRO $UBUNTU_DISTRO" - echo "" - echo "Press Ctrl+C to cancel, or Enter to continue anyway (not recommended)..." - read -r + echo "WARNING: Not running in a container. This script is designed to run in a clean Ubuntu container." + echo "" + echo "Recommended: Run in Docker with:" + echo " docker run -it --rm -v \$(pwd):/workspace -w /workspace ubuntu:$UBUNTU_DISTRO ./scripts/build_debian_packages.sh $ROS_DISTRO $UBUNTU_DISTRO" + echo "" + echo "Press Ctrl+C to cancel, or Enter to continue anyway (not recommended)..." + read -r fi # Setup ROS repository if not already configured echo "Setting up ROS repository..." export DEBIAN_FRONTEND=noninteractive export TZ=Etc/UTC -ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone +ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ >/etc/timezone apt-get update -qq apt-get install -y curl gnupg lsb-release if [ ! -f "/etc/apt/sources.list.d/ros2.list" ]; then - echo "Adding ROS 2 apt repository..." - curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg - echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" > /etc/apt/sources.list.d/ros2.list - apt-get update -qq + echo "Adding ROS 2 apt repository..." + curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg + echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" >/etc/apt/sources.list.d/ros2.list + apt-get update -qq else - echo "ROS 2 repository already configured" + echo "ROS 2 repository already configured" fi # Install dependencies @@ -106,7 +104,7 @@ echo "Installing build dependencies..." # Check if we need --break-system-packages for pip USE_BREAK_SYSTEM_PACKAGES="" if [[ "$ROS_DISTRO" == "jazzy" || "$ROS_DISTRO" == "kilted" || "$ROS_DISTRO" == "rolling" ]]; then - USE_BREAK_SYSTEM_PACKAGES="--break-system-packages" + USE_BREAK_SYSTEM_PACKAGES="--break-system-packages" fi # Install system dependencies @@ -114,13 +112,13 @@ apt-get install -y build-essential python3-pip python3-bloom python3-rosdep git # Install Python dependencies if [ -f "requirements.txt" ]; then - if [ -n "$USE_BREAK_SYSTEM_PACKAGES" ]; then - pip3 install $USE_BREAK_SYSTEM_PACKAGES -I pygments -r requirements.txt - python3 -m pip install -U $USE_BREAK_SYSTEM_PACKAGES bloom - else - pip3 install -r requirements.txt - python3 -m pip install -U bloom - fi + if [ -n "$USE_BREAK_SYSTEM_PACKAGES" ]; then + pip3 install $USE_BREAK_SYSTEM_PACKAGES -I pygments -r requirements.txt + python3 -m pip install -U $USE_BREAK_SYSTEM_PACKAGES bloom + else + pip3 install -r requirements.txt + python3 -m pip install -U bloom + fi fi # Initialize rosdep and install all build dependencies @@ -131,9 +129,9 @@ rosdep install --from-paths . --rosdistro "$ROS_DISTRO" --ignore-src -r -y # Source ROS environment (now installed via rosdep) if [ ! -f "/opt/ros/$ROS_DISTRO/setup.bash" ]; then - echo "Error: ROS $ROS_DISTRO not found after rosdep install" - echo "This should have been installed by rosdep. Check package.xml dependencies." - exit 1 + echo "Error: ROS $ROS_DISTRO not found after rosdep install" + echo "This should have been installed by rosdep. Check package.xml dependencies." + exit 1 fi source /opt/ros/$ROS_DISTRO/setup.bash @@ -168,34 +166,34 @@ mkdir -p "$DEBIAN_DIR" # Function to build a Debian package build_debian_package() { - local package_name=$1 - local package_dir=$2 + local package_name=$1 + local package_dir=$2 - echo "==================================" - echo "Generating Debian package for $package_name..." - echo "==================================" + echo "==================================" + echo "Generating Debian package for $package_name..." + echo "==================================" - cd "$package_dir" + cd "$package_dir" - # Generate debian files and build package - bloom-generate rosdebian --ros-distro "$ROS_DISTRO" - apt-get build-dep . -y || sudo apt-get build-dep . -y - fakeroot debian/rules binary + # Generate debian files and build package + bloom-generate rosdebian --ros-distro "$ROS_DISTRO" + apt-get build-dep . -y || sudo apt-get build-dep . -y + fakeroot debian/rules binary - # Move package to output directory - cp ../ros-$ROS_DISTRO-${package_name//_/-}_*.deb "../$DEBIAN_DIR/" + # Move package to output directory + cp ../ros-$ROS_DISTRO-${package_name//_/-}_*.deb "../$DEBIAN_DIR/" - cd .. + cd .. - echo "Successfully built $package_name" + echo "Successfully built $package_name" } # Function to install a package locally install_package() { - local package_pattern=$1 - echo "Installing $package_pattern..." - apt-get update || sudo apt-get update - apt-get install -y ./$DEBIAN_DIR/$package_pattern || sudo apt-get install -y ./$DEBIAN_DIR/$package_pattern + local package_pattern=$1 + echo "Installing $package_pattern..." + apt-get update || sudo apt-get update + apt-get install -y ./$DEBIAN_DIR/$package_pattern || sudo apt-get install -y ./$DEBIAN_DIR/$package_pattern } # Build packages in dependency order @@ -203,18 +201,18 @@ echo "Starting Debian package generation..." # 1. Build greenwave_monitor_interfaces if [ -d "greenwave_monitor_interfaces" ]; then - build_debian_package "greenwave_monitor_interfaces" "greenwave_monitor_interfaces" - install_package "ros-$ROS_DISTRO-greenwave-monitor-interfaces_*.deb" + build_debian_package "greenwave_monitor_interfaces" "greenwave_monitor_interfaces" + install_package "ros-$ROS_DISTRO-greenwave-monitor-interfaces_*.deb" else - echo "Warning: greenwave_monitor_interfaces directory not found, skipping" + echo "Warning: greenwave_monitor_interfaces directory not found, skipping" fi # 2. Build greenwave_monitor if [ -d "greenwave_monitor" ]; then - build_debian_package "greenwave_monitor" "greenwave_monitor" - install_package "ros-$ROS_DISTRO-greenwave-monitor_*.deb" + build_debian_package "greenwave_monitor" "greenwave_monitor" + install_package "ros-$ROS_DISTRO-greenwave-monitor_*.deb" else - echo "Warning: greenwave_monitor directory not found, skipping" + echo "Warning: greenwave_monitor directory not found, skipping" fi # Note: r2s_gw is now a separate repository and not included in debian packages diff --git a/scripts/docker-test.sh b/scripts/docker-test.sh index 16a4ebb..dc5ec0c 100755 --- a/scripts/docker-test.sh +++ b/scripts/docker-test.sh @@ -1,7 +1,7 @@ #!/bin/bash # SPDX-FileCopyrightText: NVIDIA CORPORATION & AFFILIATES -# Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -27,26 +27,26 @@ DISTRO=${1:-humble} # Image mapping based on ROS distro case $DISTRO in - humble) - IMAGE="ros:humble-ros-base-jammy" - ;; - iron) - IMAGE="ros:iron-ros-base-jammy" - ;; - jazzy) - IMAGE="ros:jazzy-ros-base-noble" - ;; - kilted) - IMAGE="ros:kilted-ros-base-noble" - ;; - rolling) - IMAGE="ros:rolling-ros-base-noble" - ;; - *) - echo "Unsupported ROS 2 distribution: $DISTRO" - echo "Supported: humble, iron, jazzy, kilted, rolling" - exit 1 - ;; +humble) + IMAGE="ros:humble-ros-base-jammy" + ;; +iron) + IMAGE="ros:iron-ros-base-jammy" + ;; +jazzy) + IMAGE="ros:jazzy-ros-base-noble" + ;; +kilted) + IMAGE="ros:kilted-ros-base-noble" + ;; +rolling) + IMAGE="ros:rolling-ros-base-noble" + ;; +*) + echo "Unsupported ROS 2 distribution: $DISTRO" + echo "Supported: humble, iron, jazzy, kilted, rolling" + exit 1 + ;; esac echo "Starting Docker container for ROS 2 $DISTRO..." @@ -57,14 +57,14 @@ WORKSPACE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/../" # Run container with interactive shell, mounting current directory docker run -it --rm \ - --name greenwave-test-${DISTRO} \ - -e ROS_LOCALHOST_ONLY=1 \ - -e ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST \ - -e ROS_DISTRO=${DISTRO} \ - -v ${WORKSPACE_DIR}:/workspace/src/greenwave_monitor \ - -w /workspace \ - ${IMAGE} \ - bash -c " + --name greenwave-test-${DISTRO} \ + -e ROS_LOCALHOST_ONLY=1 \ + -e ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST \ + -e ROS_DISTRO=${DISTRO} \ + -v ${WORKSPACE_DIR}:/workspace/src/greenwave_monitor \ + -w /workspace \ + ${IMAGE} \ + bash -c " # Source ROS setup source /opt/ros/${DISTRO}/setup.bash @@ -100,4 +100,4 @@ docker run -it --rm \ # Start interactive shell bash - " \ No newline at end of file + "