Skip to content
Open
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
11 changes: 1 addition & 10 deletions ament_clang_format/ament_clang_format/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from xml.sax.saxutils import escape
from xml.sax.saxutils import quoteattr

from ament_lint.filesystem_helpers import find_executable
import yaml


Expand Down Expand Up @@ -245,16 +246,6 @@ def main(argv=sys.argv[1:]):
return rc


def find_executable(file_names):
paths = os.getenv('PATH').split(os.path.pathsep)
for file_name in file_names:
for path in paths:
file_path = os.path.join(path, file_name)
if os.path.isfile(file_path) and os.access(file_path, os.X_OK):
return file_path
return None


def get_files(paths, extensions):
files = []
for path in paths:
Expand Down
1 change: 1 addition & 0 deletions ament_clang_format/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<author>Dirk Thomas</author>
<author email="michel@ekumenlabs.com">Michel Hidalgo</author>

<exec_depend>ament_lint</exec_depend>
<exec_depend>clang-format</exec_depend>
<exec_depend>python3-yaml</exec_depend>

Expand Down
23 changes: 23 additions & 0 deletions ament_clang_format/test/test_execution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2025 Open Source Robotics Foundation, Inc.
#
# 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.

from ament_clang_format.main import main
from ament_lint.test_helpers import TempFileWriter


def test_clang_format_execution():
"""Test that clang format can be executed on a simple C++ file, via ament_clang_format."""
with TempFileWriter('int main() { return 0; }', 'test.cpp') as temp_file_path:
rc = main(argv=['ament_clang_format', temp_file_path])
assert rc == 0, 'Clang format found issues'
11 changes: 2 additions & 9 deletions ament_clang_tidy/ament_clang_tidy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from xml.sax.saxutils import escape
from xml.sax.saxutils import quoteattr

from ament_lint.filesystem_helpers import find_executable
import yaml


Expand Down Expand Up @@ -264,15 +265,7 @@ def start_subprocess(full_cmd):
with open(args.xunit_file, 'w') as f:
f.write(xml)


def find_executable(file_names):
paths = os.getenv('PATH').split(os.path.pathsep)
for file_name in file_names:
for path in paths:
file_path = os.path.join(path, file_name)
if os.path.isfile(file_path) and os.access(file_path, os.X_OK):
return file_path
return None
return 0 if all(len(v) == 0 for v in report.values()) else 1


def get_compilation_db_files(paths):
Expand Down
1 change: 1 addition & 0 deletions ament_clang_tidy/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<author>Claire Wang</author>
<author email="michel@ekumenlabs.com">Michel Hidalgo</author>

<exec_depend>ament_lint</exec_depend>
<exec_depend>clang-tidy</exec_depend>
<exec_depend>python3-yaml</exec_depend>

Expand Down
40 changes: 40 additions & 0 deletions ament_clang_tidy/test/test_execution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2025 Open Source Robotics Foundation, Inc.
#
# 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.

import json
from pathlib import Path

from ament_clang_tidy.main import main
from ament_lint.test_helpers import TempFileWriter


def test_clang_tidy_execution():
"""Test that clang tidy can be executed on a simple C++ file, via ament_clang_tidy."""
with TempFileWriter('int main() { return 0; }', 'test.cpp') as temp_file_path:
temp_dir = Path(temp_file_path).parent

# Create compile_commands.json
compile_commands = [
{
'directory': str(temp_dir),
'command': 'c++ -c test.cpp',
'file': str(temp_file_path),
}
]
compile_commands_json = json.dumps(compile_commands)
with TempFileWriter(
compile_commands_json, 'compile_commands.json'
) as compile_commands_path:
rc = main(argv=['ament_clang_tidy', str(compile_commands_path)])
assert rc == 0, 'Clang tidy found issues'
22 changes: 22 additions & 0 deletions ament_lint/ament_lint/filesystem_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2025 Open Source Robotics Foundation, Inc.
#
# 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.

import shutil

def find_executable(file_names: list[str]) -> str | None:
for name in file_names:
found = shutil.which(name)
if found:
return found
return None
44 changes: 44 additions & 0 deletions ament_lint/ament_lint/test_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Copyright 2025 Open Source Robotics Foundation, Inc.
#
# 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.

import tempfile
import os

class TempFileWriter:
"""Context manager that writes a string to a temp file and cleans up on exit."""

def __init__(self, content, filename):
self.content = content
self.filename = filename
self.temp_dir = None
self.temp_file = None

def __enter__(self):
# Create a new temporary directory
self.temp_dir = tempfile.mkdtemp()
# Create the temp file path
self.temp_file = os.path.join(self.temp_dir, self.filename)
# Write content to the file
with open(self.temp_file, 'w') as f:
f.write(self.content)
return self.temp_file

def __exit__(self, exc_type, exc_val, exc_tb):
# Remove the file
if self.temp_file and os.path.exists(self.temp_file):
os.remove(self.temp_file)
# Remove the directory
if self.temp_dir and os.path.exists(self.temp_dir):
os.rmdir(self.temp_dir)
return False