Skip to content

Commit c25d55a

Browse files
authored
Feature/focus_modes (#14)
* missing deps only * added focus modes and further improved test coverage * fixed bug in test
1 parent d06acab commit c25d55a

26 files changed

Lines changed: 1234 additions & 109 deletions

Readme.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ options:
6767
--skip-rosdep-key-validation Check if rosdeps are valid.
6868
--compare-with-cmake Check if all CMake dependencies are in package.xml.
6969
--auto-fill-missing-deps Automatically fill missing dependencies in package.xml.
70+
--missing-deps-only Only report missing dependencies (implies --check-only).
71+
--ignore-formatting-errors Skip formatting-only checks (implies --check-only).
7072
```
7173
Example with verbose logging:
7274
```
@@ -143,3 +145,8 @@ This will:
143145
- Exit non-zero if any problems are found
144146
→ **No files will be modified**
145147
- if rosdep is not available in the CI environment use the `--skip-rosdep-key-validation` flag
148+
149+
### 🎯 Focused modes
150+
151+
- `--missing-deps-only`: Skip all formatting and schema checks and only report missing dependencies (including launch/test dependencies).
152+
- `--ignore-formatting-errors`: Run all critical checks while ignoring pure formatting issues like indentation or ordering. This mode is check-only and will not rewrite files.

package_xml_validation/helpers/pkg_xml_formatter.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,14 @@ def check_element_occurrences(self, root, xml_file):
198198
count = len(root.findall(elem))
199199
if count < min_occurrences:
200200
self.logger.info(
201-
f"Error: Element '{elem}' in {xml_file} has fewer than {min_occurrences} occurrences."
201+
f"Error: Element <{elem}> in {xml_file} has fewer than {min_occurrences} occurrences."
202202
)
203203
incorrect_occurrences = True
204204
if self.check_only:
205205
return False
206206
elif max_occurrences is not None and count > max_occurrences:
207207
self.logger.info(
208-
f"Error: Element '{elem}' in {xml_file} has more than {max_occurrences} occurrences."
208+
f"Error: Element <{elem}> in {xml_file} has more than {max_occurrences} occurrences."
209209
)
210210
incorrect_occurrences = True
211211
if self.check_only:
@@ -219,12 +219,29 @@ def check_element_occurrences(self, root, xml_file):
219219

220220
# Correct the occurrences
221221
for elem, min_occurrence, max_occurrences in ELEMENTS:
222-
count = len(root.findall(elem))
222+
elements = root.findall(elem)
223+
count = len(elements)
223224
if max_occurrences is not None and count > max_occurrences:
224-
for i in range(count - max_occurrences):
225-
root.remove(root.find(elem))
225+
reference = (
226+
ET.tostring(elements[0], with_tail=False)
227+
if len(elements) > 0
228+
else None
229+
)
230+
if reference and all(
231+
ET.tostring(elm, with_tail=False) == reference
232+
for elm in elements[1:]
233+
):
234+
for extra in elements[max_occurrences:]:
235+
root.remove(extra)
236+
self.logger.info(
237+
f"Removed identical duplicate element <{elem}> from {xml_file}."
238+
)
239+
else:
240+
self.logger.warning(
241+
f"Multiple <{elem}> entries differ. Please resolve manually. There are {count} occurrences in {xml_file} but there should be no more than {max_occurrences}."
242+
)
226243
if count < min_occurrence:
227-
self.logger.info("Please add the missing element: ", elem)
244+
self.logger.warning(f"Please add the missing element: <{elem}>")
228245
return False
229246

230247
def check_element_order(self, root, xml_file):
@@ -431,7 +448,7 @@ def check_for_non_existing_tags(self, root, xml_file):
431448
non_existing_tags.append(elem.tag)
432449
if non_existing_tags:
433450
self.logger.error(
434-
f"Non-existing tags found in {xml_file}: {', '.join(non_existing_tags)}"
451+
f"Unknown tags found in {xml_file}: {', '.join(non_existing_tags)}"
435452
)
436453
return False
437454
return True

0 commit comments

Comments
 (0)