moveit2
The MoveIt Motion Planning Framework for ROS 2.
Loading...
Searching...
No Matches
create_deprecated_headers.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3
4# Copyright 2024 Tom Noble.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are met:
8#
9# * Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11#
12# * Redistributions in binary form must reproduce the above copyright
13# notice, this list of conditions and the following disclaimer in the
14# documentation and/or other materials provided with the distribution.
15#
16# * Neither the name of the copyright holder nor the names of its
17# contributors may be used to endorse or promote products derived from
18# this software without specific prior written permission.
19#
20# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30# POSSIBILITY OF SUCH DAMAGE.
31
32# Author: Tom Noble
33
34import sys
35import argparse
36import logging
37from typing import List, Tuple
38from pathlib import Path
39
40
41DISCLAIMER = """
42/*********************************************************************
43 * All MoveIt 2 headers have been updated to use the .hpp extension.
44 *
45 * .h headers are now autogenerated via {},
46 * and will import the corresponding .hpp with a deprecation warning.
47 *
48 * imports via .h files may be removed in future releases, so please
49 * modify your imports to use the corresponding .hpp imports.
50 *
51 * See https://github.com/moveit/moveit2/pull/3113 for extra details.
52 *********************************************************************/
53"""
54
55
56class NoIncludeGuard(Exception):
57 ERROR = "No include guard found in {}.hpp. Unable to generate pretext."
58
59 def __init__(self, file: Path):
60 super().__init__(self.ERROR.format(file))
61
62
63class NoIncludeDirectory(Exception):
64 ERROR = "No include directory found for {}.hpp. Unable to generate relative .hpp include"
65
66 def __init__(self, file: Path):
67 super().__init__(self.ERROR.format(file))
68
69
70class HppFile:
71 def __init__(self, path: Path):
72 self.path = path
73 self.guard = "#pragma once"
76
77 def drop_data_after(self, data: str, match: str):
78 return data[: data.find(match) + len(match)]
79
80 def read(self) -> str:
81 data = open(self.path, "r").read()
82 contains_guard = self.guard in data
83 if not contains_guard:
84 raise NoIncludeGuard(self.path)
85 return data
86
87 def pretext(self) -> str:
88 data = self.read()
89 return self.drop_data_after(data, self.guard)
90
91 def include(self) -> str:
92 ends_with_include = lambda p: str(p).endswith("include")
93 include_paths = [p for p in self.path.parents if ends_with_include(p)]
94 if not include_paths:
95 raise NoIncludeDirectory(self.path)
96 relative_import = self.path.relative_to(include_paths[0])
97 return f"#include <{relative_import}>"
98
99
101 def __init__(self, hpp: HppFile):
102 self.hpp = hpp
103 self.path = hpp.path.with_suffix(".h")
104 self.warn = '#pragma message(".h header is obsolete. Please use the .hpp header instead.")'
106
107 def contents(self) -> str:
108 disclaimer = DISCLAIMER.format(Path(__file__).name).rstrip("\n")
109 items = [disclaimer, self.hpp.pretext, self.warn, self.hpp.include]
110 return "\n".join(items) + "\n"
111
112
114 def __init__(self, n_processed_hpps: int, bad_hpps: List[str]):
115 self.n_processed_hpps = n_processed_hpps
116 self.bad_hpps = bad_hpps
117
118 def were_all_hpps_processed(self) -> bool:
119 return len(self.bad_hpps) == 0
120
121 def __repr__(self) -> str:
122 summary = f"Can generate {self.n_processed_hpps} .h files."
123 if self.bad_hpps:
124 summary += f" Cannot generate {len(self.bad_hpps)} .h files:\n\n"
125 summary += "\n".join([f"❌ {hpp}" for hpp in self.bad_hpps])
126 summary += "\n"
127 return summary
128
129
131 def __init__(self, hpp_paths: List[str]):
132 self.hpp_paths = hpp_paths
134 self.bad_hpps = []
135
136 def __process_hpp(self, hpp: str) -> None:
137 try:
138 self.processed_hpps.append(HppFile(hpp))
139 except (NoIncludeDirectory, NoIncludeGuard) as e:
140 self.bad_hpps.append(str(hpp))
141
142 def process_all_hpps(self) -> HeaderSummary:
143 print(f"\nProcessing {len(self.hpp_paths)} .hpp files...")
144 _ = [self.__process_hpp(hpp) for hpp in self.hpp_paths]
145 return HeaderSummary(len(self.processed_hpps), self.bad_hpps)
146
147 def create_h_files(self) -> None:
148 print(f"Proceeding to generate {len(self.processed_hpps)} .h files...")
149 h_files = [DeprecatedHeader(hpp) for hpp in self.processed_hpps]
150 _ = [open(h.path, "w").write(h.contents) for h in h_files]
151
152
153if __name__ == "__main__":
154 parser = argparse.ArgumentParser()
155 # TODO: Add argument for skipping private headers
156 parser.add_argument("--apply", action="store_true", help="Generates the .h files")
157 args = parser.parse_args()
158 generator = DeprecatedHeaderGenerator(list(Path.cwd().rglob("*.hpp")))
159 summary = generator.process_all_hpps()
160 print(summary)
161 if args.apply and not summary.were_all_hpps_processed():
162 args.apply = input("Continue? (y/n): ").lower() == "y"
163 if args.apply:
164 generator.create_h_files()
165 else:
166 print("Skipping file generation...")
167 print("Done.\n")
__init__(self, int n_processed_hpps, List[str] bad_hpps)
KeyboardReader input
void print(PropagationDistanceField &pdf, int numX, int numY, int numZ)