diff --git a/rosdoc2/verbs/build/build_context.py b/rosdoc2/verbs/build/build_context.py index 3e0d96e..3b4af68 100644 --- a/rosdoc2/verbs/build/build_context.py +++ b/rosdoc2/verbs/build/build_context.py @@ -29,5 +29,7 @@ def __init__(self, *, configuration_file_path, package_object, tool_options): self.build_type = package_object.get_build_type() self.python_source = None self.always_run_doxygen = False + self.never_run_doxygen = False self.always_run_sphinx_apidoc = False + self.never_run_sphinx_apidoc = False self.ament_cmake_python = False diff --git a/rosdoc2/verbs/build/builders/doxygen_builder.py b/rosdoc2/verbs/build/builders/doxygen_builder.py index ed89122..1553bc1 100644 --- a/rosdoc2/verbs/build/builders/doxygen_builder.py +++ b/rosdoc2/verbs/build/builders/doxygen_builder.py @@ -82,6 +82,10 @@ def __init__(self, builder_name, builder_entry_dictionary, build_context): assert self.builder_type == 'doxygen' self.name = self.name or self.build_context.package.name + ' Public C/C++ API' self.output_dir = self.output_dir or 'generated/doxygen' + self.doxyfile = None + self.extra_doxyfile_statements = [] + self.rosdoc2_doxyfile_statements = [] + self.doxyfile_content = None # If the build type is not `ament_cmake/cmake`, there is no reason # to create a doxygen builder. @@ -93,13 +97,12 @@ def __init__(self, builder_name, builder_entry_dictionary, build_context): f"The package build type is not 'ament_cmake' or 'cmake', hence the " f"'{self.builder_type}' builder was not configured") return - - self.doxyfile = None - self.extra_doxyfile_statements = [] - self.rosdoc2_doxyfile_statements = [] - configuration_file_path = build_context.configuration_file_path + elif self.build_context.never_run_doxygen: + logger.debug('The package has never_run_doxygen set, so skipping doxygen.') + return # Process keys. + configuration_file_path = build_context.configuration_file_path for key, value in builder_entry_dictionary.items(): if key in ['name', 'output_dir']: continue @@ -132,7 +135,6 @@ def __init__(self, builder_name, builder_entry_dictionary, build_context): # Prepare the template variables for formatting strings. self.template_variables = create_format_map_from_package(build_context.package) - self.doxyfile_content = None # If the user does not supply a Doxygen file, look for one in the package root. if self.doxyfile is None: package_directory = os.path.dirname(build_context.package.filename) @@ -179,6 +181,10 @@ def build(self, *, doc_build_folder, output_staging_directory): f"'{self.builder_type}' builder was not invoked") return None # Explicitly generated no documentation. + if self.build_context.never_run_doxygen: + logger.info('The package has never_run_doxygen set, so skipping doxygen.') + return None + # If both doxyfile and doxyfile_content are None, that means there is # no reason to run doxygen. if self.doxyfile is None and self.doxyfile_content is None: diff --git a/rosdoc2/verbs/build/builders/sphinx_builder.py b/rosdoc2/verbs/build/builders/sphinx_builder.py index 348889c..4188170 100644 --- a/rosdoc2/verbs/build/builders/sphinx_builder.py +++ b/rosdoc2/verbs/build/builders/sphinx_builder.py @@ -542,9 +542,14 @@ def build(self, *, doc_build_folder, output_staging_directory): ] build_context = self.build_context - has_python = build_context.build_type == 'ament_python' or \ - build_context.always_run_sphinx_apidoc or \ - build_context.ament_cmake_python + if build_context.never_run_sphinx_apidoc: + logger.info( + 'The package has never_run_sphinx_apidoc set, so sphinx apidoc will not be run.') + has_python = ( + build_context.build_type == 'ament_python' + or build_context.always_run_sphinx_apidoc + or build_context.ament_cmake_python) \ + and not build_context.never_run_sphinx_apidoc self.template_variables.update({ 'has_python': has_python, diff --git a/rosdoc2/verbs/build/inspect_package_for_settings.py b/rosdoc2/verbs/build/inspect_package_for_settings.py index ca620e9..1294c02 100644 --- a/rosdoc2/verbs/build/inspect_package_for_settings.py +++ b/rosdoc2/verbs/build/inspect_package_for_settings.py @@ -46,11 +46,22 @@ ## of the `ament_cmake/cmake` build type. # always_run_doxygen: false, + ## This setting, if true, will skip running doxygen` and the `breathe`/`exhale` + ## extensions to `sphinx` regardless of build type. This is most useful if the + ## user has generated C++ documentation elsewhere that is included in the doc + ## folder, or in external documentation. + # never_run_doxygen: false, + ## This setting, if true, attempts to run `sphinx-apidoc` regardless of build ## type. This is most useful if the user would like to generate Python API ## documentation for a package that is not of the `ament_python` build type. # always_run_sphinx_apidoc: false, + ## This setting, if true, will skip running `sphinx-apidoc` regardless of build + ## type. This is most useful if the user has generated python documentation elsewhere + ## that is included in the doc folder, or in external documentation. + # never_run_sphinx_apidoc: false, + ## This setting, if provided, will override the build_type of this package ## for documentation purposes only. If not provided, documentation will be ## generated assuming the build_type in package.xml. @@ -196,7 +207,9 @@ def inspect_package_for_settings(package, tool_options): # if None, python_source is set to either './' or 'src/' build_context.python_source = settings_dict.get('python_source', None) build_context.always_run_doxygen = settings_dict.get('always_run_doxygen', False) + build_context.never_run_doxygen = settings_dict.get('never_run_doxygen', False) build_context.always_run_sphinx_apidoc = settings_dict.get('always_run_sphinx_apidoc', False) + build_context.never_run_sphinx_apidoc = settings_dict.get('never_run_sphinx_apidoc', False) build_context.build_type = settings_dict.get('override_build_type', build_context.build_type) builders = [] diff --git a/test/packages/default_yaml/rosdoc2.yaml b/test/packages/default_yaml/rosdoc2.yaml index 2dec477..15b4f5b 100644 --- a/test/packages/default_yaml/rosdoc2.yaml +++ b/test/packages/default_yaml/rosdoc2.yaml @@ -19,11 +19,22 @@ settings: { ## of the `ament_cmake/cmake` build type. always_run_doxygen: false, + ## This setting, if true, will skip running doxygen` and the `breathe`/`exhale` + ## extensions to `sphinx` regardless of build type. This is most useful if the + ## user has generated C++ documentation elsewhere that is included in the doc + ## folder, or in external documentation. + never_run_doxygen: false, + ## This setting, if true, attempts to run `sphinx-apidoc` regardless of build ## type. This is most useful if the user would like to generate Python API ## documentation for a package that is not of the `ament_python` build type. always_run_sphinx_apidoc: false, + ## This setting, if true, will skip running `sphinx-apidoc` regardless of build + ## type. This is most useful if the user has generated python documentation elsewhere + ## that is included in the doc folder, or in external documentation. + never_run_sphinx_apidoc: false, + ## This setting, if provided, will override the build_type of this package ## for documentation purposes only. If not provided, documentation will be ## generated assuming the build_type in package.xml. diff --git a/test/packages/never_doxygen/CMakeLists.txt b/test/packages/never_doxygen/CMakeLists.txt new file mode 100644 index 0000000..85e1d00 --- /dev/null +++ b/test/packages/never_doxygen/CMakeLists.txt @@ -0,0 +1,35 @@ +cmake_minimum_required(VERSION 3.8) +project(never_doxygen) + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + add_compile_options(-Wall -Wextra -Wpedantic) +endif() + +# find dependencies +find_package(ament_cmake REQUIRED) +# uncomment the following section in order to fill in +# further dependencies manually. +# find_package( REQUIRED) + +add_executable(test_node src/test_node.cpp) +target_include_directories(test_node PUBLIC + $ + $) +target_compile_features(test_node PUBLIC c_std_99 cxx_std_17) # Require C99 and C++17 + +install(TARGETS test_node + DESTINATION lib/${PROJECT_NAME}) + +if(BUILD_TESTING) + find_package(ament_lint_auto REQUIRED) + # the following line skips the linter which checks for copyrights + # comment the line when a copyright and license is added to all source files + set(ament_cmake_copyright_FOUND TRUE) + # the following line skips cpplint (only works in a git repo) + # comment the line when this package is in a git repo and when + # a copyright and license is added to all source files + set(ament_cmake_cpplint_FOUND TRUE) + ament_lint_auto_find_test_dependencies() +endif() + +ament_package() diff --git a/test/packages/never_doxygen/include/never_doxygen/test_node.hpp b/test/packages/never_doxygen/include/never_doxygen/test_node.hpp new file mode 100644 index 0000000..77308c2 --- /dev/null +++ b/test/packages/never_doxygen/include/never_doxygen/test_node.hpp @@ -0,0 +1,27 @@ +// +// Copyright 2024 R. Kent James +// +// 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. + +#ifndef NEVER_DOXYGEN__TEST_NODE_HPP_ +#define NEVER_DOXYGEN__TEST_NODE_HPP_ + +/// @file +/// @brief This is an include file to go with the C++ file generated by `ros2 pkg create` + +/** + This demo program just prints hello world. + */ +int main(int argc, char ** argv) + +#endif // NEVER_DOXYGEN__TEST_NODE_HPP_ diff --git a/test/packages/never_doxygen/package.xml b/test/packages/never_doxygen/package.xml new file mode 100644 index 0000000..8b64288 --- /dev/null +++ b/test/packages/never_doxygen/package.xml @@ -0,0 +1,19 @@ + + + + never_doxygen + 0.0.0 + Basic c++ package with never_run_doxygen set + ros2 user + Apache 2.0 + + ament_cmake + + ament_lint_auto + ament_lint_common + + + ament_cmake + rosdoc2.yaml + + diff --git a/test/packages/never_doxygen/rosdoc2.yaml b/test/packages/never_doxygen/rosdoc2.yaml new file mode 100644 index 0000000..af9d30b --- /dev/null +++ b/test/packages/never_doxygen/rosdoc2.yaml @@ -0,0 +1,18 @@ +## This 'attic section' self-documents this file's type and version. +type: 'rosdoc2 config' +version: 1 + +--- + +settings: { + ## This setting, if true, will skip running doxygen` and the `breathe`/`exhale` + ## extensions to `sphinx` regardless of build type. This is most useful if the + ## user has generated C++ documentation elsewhere that is included in the doc + ## folder, or in external documentation. + never_run_doxygen: true, +} +builders: + - doxygen: { + } + - sphinx: { + } diff --git a/test/packages/never_doxygen/src/test_node.cpp b/test/packages/never_doxygen/src/test_node.cpp new file mode 100644 index 0000000..7f7feb1 --- /dev/null +++ b/test/packages/never_doxygen/src/test_node.cpp @@ -0,0 +1,10 @@ +#include + +int main(int argc, char ** argv) +{ + (void) argc; + (void) argv; + + printf("hello world never_doxygen package\n"); + return 0; +} diff --git a/test/packages/never_sphinx_apidoc/README.txt b/test/packages/never_sphinx_apidoc/README.txt new file mode 100644 index 0000000..c405d7f --- /dev/null +++ b/test/packages/never_sphinx_apidoc/README.txt @@ -0,0 +1 @@ +This is a README as simple text. diff --git a/test/packages/never_sphinx_apidoc/never_sphinx_apidoc/__init__.py b/test/packages/never_sphinx_apidoc/never_sphinx_apidoc/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/packages/never_sphinx_apidoc/never_sphinx_apidoc/python_node.py b/test/packages/never_sphinx_apidoc/never_sphinx_apidoc/python_node.py new file mode 100644 index 0000000..37e7dc2 --- /dev/null +++ b/test/packages/never_sphinx_apidoc/never_sphinx_apidoc/python_node.py @@ -0,0 +1,6 @@ +def main(): + print('Hi from never_sphinx_apidoc.') + + +if __name__ == '__main__': + main() diff --git a/test/packages/never_sphinx_apidoc/package.xml b/test/packages/never_sphinx_apidoc/package.xml new file mode 100644 index 0000000..9ded4ac --- /dev/null +++ b/test/packages/never_sphinx_apidoc/package.xml @@ -0,0 +1,19 @@ + + + + never_sphinx_apidoc + 0.0.0 + Python but sphinx api disabled + Ye ol' Python Pro + Apache-2.0 + + ament_copyright + ament_flake8 + ament_pep257 + python3-pytest + + + ament_python + rosdoc2.yaml + + diff --git a/test/packages/never_sphinx_apidoc/rosdoc2.yaml b/test/packages/never_sphinx_apidoc/rosdoc2.yaml new file mode 100644 index 0000000..584594f --- /dev/null +++ b/test/packages/never_sphinx_apidoc/rosdoc2.yaml @@ -0,0 +1,17 @@ +## This 'attic section' self-documents this file's type and version. +type: 'rosdoc2 config' +version: 1 + +--- + +settings: { + ## This setting, if true, will skip running `sphinx-apidoc` regardless of build + ## type. This is most useful if the user has generated python documentation elsewhere + ## that is included in the doc folder, or in external documentation. + never_run_sphinx_apidoc: true, +} +builders: + - doxygen: { + } + - sphinx: { + } diff --git a/test/packages/never_sphinx_apidoc/setup.cfg b/test/packages/never_sphinx_apidoc/setup.cfg new file mode 100644 index 0000000..da83911 --- /dev/null +++ b/test/packages/never_sphinx_apidoc/setup.cfg @@ -0,0 +1,4 @@ +[develop] +script_dir=$base/lib/never_sphinx_apidoc +[install] +install_scripts=$base/lib/never_sphinx_apidoc diff --git a/test/packages/never_sphinx_apidoc/setup.py b/test/packages/never_sphinx_apidoc/setup.py new file mode 100644 index 0000000..553843c --- /dev/null +++ b/test/packages/never_sphinx_apidoc/setup.py @@ -0,0 +1,26 @@ +from setuptools import find_packages, setup + +package_name = 'never_sphinx_apidoc' + +setup( + name=package_name, + version='0.0.0', + packages=find_packages(exclude=['test']), + data_files=[ + ('share/ament_index/resource_index/packages', + ['resource/' + package_name]), + ('share/' + package_name, ['package.xml']), + ], + install_requires=['setuptools'], + zip_safe=True, + maintainer='kent', + maintainer_email='kent@caspia.com', + description='TODO: Package description', + license='TODO: License declaration', + tests_require=['pytest'], + entry_points={ + 'console_scripts': [ + 'python_node = never_sphinx_apidoc.python_node:main' + ], + }, +) diff --git a/test/test_builder.py b/test/test_builder.py index 0047cf5..b518cd6 100644 --- a/test/test_builder.py +++ b/test/test_builder.py @@ -57,6 +57,36 @@ def do_build_package(package_path, work_path, with_extension=False) -> None: main_impl(options) +def test_never_sphinx_apidoc(module_dir): + """Tests of never_run_sphinx_apidoc.""" + PKG_NAME = 'never_sphinx_apidoc' + do_build_package(DATAPATH / PKG_NAME, module_dir) + + includes = [ + PKG_NAME, + ] + + excludes = ['python api'] # No python api generated since never_run_sphinx_apidoc is set + + do_test_package(PKG_NAME, module_dir, + includes=includes, excludes=excludes) + + +def test_never_doxygen(module_dir): + """Tests of never_run_doxygen.""" + PKG_NAME = 'never_doxygen' + do_build_package(DATAPATH / PKG_NAME, module_dir) + + includes = [ + PKG_NAME, + ] + + excludes = ['c++ api'] # No c++ api since never_run_doxygen set + + do_test_package(PKG_NAME, module_dir, + includes=includes, excludes=excludes) + + def test_minimum_package(module_dir): """Tests of a package containing as little as possible.""" PKG_NAME = 'minimum_package'