Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

List meta dependencies in meta packages #114

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
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
9 changes: 9 additions & 0 deletions rosdoc2/verbs/build/builders/index.rst.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@
{% if interface_counts['srv'] > 0 %} Service Definitions <interfaces/service_definitions>{% endif %}
{% if interface_counts['action'] > 0 %} Action Definitions <interfaces/action_definitions>{% endif %}
{% if has_standard_docs %} Standard Documents <standards>{% endif %}
{% if show_exec_dep %}

Execution Dependencies of this package
--------------------------------------
{% for dependency in package.exec_depends -%}
* `{{ dependency }} <{{ base_url }}/{{ dependency }}>`_
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Injecting the base_url here means that the inter package content jumps out of the local tree of a local build tree, or a mirror etc. I think everything else generally uses relative paths and thus is easily testable in the local location and relocatable. Overall using base_url makes sense, but maybe having the default be "." such that everything is relative. Otherwise we really need to flesh out the documentation and deployment stories. It's a challenge to have to test all the docs at one URL or file path. But then have to rebuild them to deploy. Before this the only locations using the base_url are the doxygen tags and sphinx inventory files which actually might be helpful for leveraging cross referencing. But also might have issues if we get to supporting them locally for cross referncing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK I'll modify this according to your comments, but it might take a few days because this is a busy week for me.

{% endfor -%}
{% endif -%}

{% if has_documentation %}
.. toctree::
:titlesonly:
Expand Down
30 changes: 29 additions & 1 deletion rosdoc2/verbs/build/builders/sphinx_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import json
import logging
import os
from pathlib import Path
import shutil
import subprocess

Expand Down Expand Up @@ -471,14 +472,41 @@ def build(self, *, doc_build_folder, output_staging_directory):

always_run_doxygen = build_context.always_run_doxygen
has_cpp = build_context.build_type in ['ament_cmake', 'cmake'] or always_run_doxygen
package = self.build_context.package

show_exec_dep = build_context.show_exec_dep
if show_exec_dep is None:
if package.is_metapackage():
show_exec_dep = True
logger.info('show_exec_dep set True because is_metapackage set in package.xml')
# Detect meta packages. They have no build_dependencies, do have exec_dependencies,
# and have no subdirectories except for possibly 'doc'.
elif package.build_depends or not package.exec_depends:
show_exec_dep = False
logger.info("show_exec_dep set False because depends don't match meta pattern")
else:
pp = Path(package_xml_directory)
subdirectories = [x for x in pp.iterdir() if x.is_dir()]
for subdirectory in subdirectories:
if subdirectory.name != 'doc':
show_exec_dep = False
logger.info('show_exec_dep set False because non-"doc/" directory found')
continue
if show_exec_dep is None:
show_exec_dep = True
logger.info('show_exec_dep set True as package matches meta pattern')
else:
logger.info(f'show_exec_dep set to {show_exec_dep} in rosdoc2.yml')
self.template_variables.update({
'has_python': has_python,
'has_cpp': has_cpp,
'has_standard_docs': bool(standard_docs),
'has_documentation': bool(doc_directories),
'has_readme': 'readme' in standard_docs,
'interface_counts': interface_counts,
'package': self.build_context.package,
'package': package,
'base_url': base_url,
'show_exec_dep': show_exec_dep,
})

# Setup rosdoc2 Sphinx file which will include and extend the one in
Expand Down
2 changes: 1 addition & 1 deletion rosdoc2/verbs/build/impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def prepare_arguments(parser):
parser.add_argument(
'--base-url',
'-u',
default='http://docs.ros.org/en/latest/p',
default='http://docs.ros.org/en/rolling/p',
help='The base url where the package docs will be hosted, used to configure tag files.',
)
parser.add_argument(
Expand Down
8 changes: 8 additions & 0 deletions rosdoc2/verbs/build/inspect_package_for_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@
# for documentation purposes only. If not provided, documentation will be
# generated assuming the build_type in package.xml.
# override_build_type: 'ament_python'

# This boolean setting, if provided, determines whether the external dependencies of a package
# are shown in the home page of the documentation, which is useful for packages that are only
# used to force loading of other packages (which are sometimes called meta packages).
# If not set, then the decision to show the external dependencies is made on the following
# heuristics: show if the package has no build_depend, does have exec_depend, and has no
# subdirectories except an optional doc/ subdirectory.
# show_exec_dep: None
builders:
## Each stanza represents a separate build step, performed by a specific 'builder'.
## The key of each stanza is the builder to use; this must be one of the
Expand Down
1 change: 1 addition & 0 deletions rosdoc2/verbs/build/parse_rosdoc2_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def parse_rosdoc2_yaml(yaml_string, build_context):
build_context.always_run_doxygen = settings_dict.get('always_run_doxygen', False)
build_context.always_run_sphinx_apidoc = settings_dict.get('always_run_sphinx_apidoc', False)
build_context.build_type = settings_dict.get('override_build_type', build_context.build_type)
build_context.show_exec_dep = settings_dict.get('show_exec_dep', None)

if 'builders' not in config:
raise ValueError(
Expand Down
17 changes: 17 additions & 0 deletions test/packages/do_show_dep/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>do_show_dep</name>
<version>0.1.2</version>
<description>forcing show of exec dependencies</description>
<maintainer email="[email protected]">Some One</maintainer>
<license>Apache License 2.0</license>
<depend>basic_cpp</depend>
<exec_depend>full_package</exec_depend>
<exec_depend>minimum_package</exec_depend>
<exec_depend>only_messages</exec_depend>
<exec_depend>only_python</exec_depend>
<export>
<rosdoc2>rosdoc2.yaml</rosdoc2>
</export>
</package>
70 changes: 70 additions & 0 deletions test/packages/do_show_dep/rosdoc2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
## Default configuration, generated by rosdoc2.

## This 'attic section' self-documents this file's type and version.
type: 'rosdoc2 config'
version: 1

---

settings:
## If this is true, a standard index page is generated in the output directory.
## It uses the package information from the 'package.xml' to show details
## about the package, creates a table of contents for the various builders
## that were run, and may contain links to things like build farm jobs for
## this package or links to other versions of this package.

## If false, you can still include content that would have been in the index
## into one of your '.rst' files from your Sphinx project, using the
## '.. include::' directive in Sphinx.
## For example, you could include it in a custom 'index.rst' so you can have
## the standard information followed by custom content.

## TODO(wjwwood): provide a concrete example of this (relative path?)

## If this is not specified explicitly, it defaults to 'true'.
generate_package_index: true

## This setting, if true, attempts to run `doxygen` and the `breathe`/`exhale`
## extensions to `sphinx` regardless of build type. This is most useful if the
## user would like to generate C/C++ API documentation for a package that is not
## of the `ament_cmake/cmake` build type.
always_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 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.
# override_build_type: 'ament_python'

# This boolean setting, if provided, determines whether the external dependencies of a package
# are shown in the home page of the documentation, which is useful for packages that are only
# used to force loading of other packages (which are sometimes called meta packages).
# If not set, then the decision to show the external dependencies is made on the following
# heuristics: show if the package has no build_depend, does have exec_depend, and has no
# subdirectories except an optional doc/ subdirectory.
show_exec_dep: true
builders:
## Each stanza represents a separate build step, performed by a specific 'builder'.
## The key of each stanza is the builder to use; this must be one of the
## available builders.
## The value of each stanza is a dictionary of settings for the builder that
## outputs to that directory.
## Required keys in the settings dictionary are:
## * 'output_dir' - determines output subdirectory for builder instance
## relative to --output-directory
## * 'name' - used when referencing the built docs from the index.

- doxygen: {
name: 'forcing show of exec dependecies',
output_dir: 'generated/doxygen'
}
- sphinx: {
name: 'do_show_dep',
## This path is relative to output staging.
doxygen_xml_directory: 'generated/doxygen/xml',
output_dir: ''
}
17 changes: 17 additions & 0 deletions test/packages/dont_show_dep/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>dont_show_dep</name>
<version>0.1.2</version>
<description>explicitly not showing dependencies</description>
<maintainer email="[email protected]">Some One</maintainer>
<license>Apache License 2.0</license>
<exec_depend>basic_cpp</exec_depend>
<exec_depend>full_package</exec_depend>
<exec_depend>minimum_package</exec_depend>
<exec_depend>only_messages</exec_depend>
<exec_depend>only_python</exec_depend>
<export>
<rosdoc2>rosdoc2.yaml</rosdoc2>
</export>
</package>
70 changes: 70 additions & 0 deletions test/packages/dont_show_dep/rosdoc2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
## Default configuration, generated by rosdoc2.

## This 'attic section' self-documents this file's type and version.
type: 'rosdoc2 config'
version: 1

---

settings:
## If this is true, a standard index page is generated in the output directory.
## It uses the package information from the 'package.xml' to show details
## about the package, creates a table of contents for the various builders
## that were run, and may contain links to things like build farm jobs for
## this package or links to other versions of this package.

## If false, you can still include content that would have been in the index
## into one of your '.rst' files from your Sphinx project, using the
## '.. include::' directive in Sphinx.
## For example, you could include it in a custom 'index.rst' so you can have
## the standard information followed by custom content.

## TODO(wjwwood): provide a concrete example of this (relative path?)

## If this is not specified explicitly, it defaults to 'true'.
generate_package_index: true

## This setting, if true, attempts to run `doxygen` and the `breathe`/`exhale`
## extensions to `sphinx` regardless of build type. This is most useful if the
## user would like to generate C/C++ API documentation for a package that is not
## of the `ament_cmake/cmake` build type.
always_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 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.
# override_build_type: 'ament_python'

# This boolean setting, if provided, determines whether the external dependencies of a package
# are shown in the home page of the documentation, which is useful for packages that are only
# used to force loading of other packages (which are sometimes called meta packages).
# If not set, then the decision to show the external dependencies is made on the following
# heuristics: show if the package has no build_depend, does have exec_depend, and has no
# subdirectories except an optional doc/ subdirectory.
show_exec_dep: false
builders:
## Each stanza represents a separate build step, performed by a specific 'builder'.
## The key of each stanza is the builder to use; this must be one of the
## available builders.
## The value of each stanza is a dictionary of settings for the builder that
## outputs to that directory.
## Required keys in the settings dictionary are:
## * 'output_dir' - determines output subdirectory for builder instance
## relative to --output-directory
## * 'name' - used when referencing the built docs from the index.

- doxygen: {
name: 'explicitly not showing dependencies',
output_dir: 'generated/doxygen'
}
- sphinx: {
name: 'dont_show_dep',
## This path is relative to output staging.
doxygen_xml_directory: 'generated/doxygen/xml',
output_dir: ''
}
14 changes: 14 additions & 0 deletions test/packages/meta_package/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>meta_package</name>
<version>0.1.2</version>
<description>Meta package</description>
<maintainer email="[email protected]">Some One</maintainer>
<license>Apache License 2.0</license>
<exec_depend>basic_cpp</exec_depend>
<exec_depend>full_package</exec_depend>
<exec_depend>minimum_package</exec_depend>
<exec_depend>only_messages</exec_depend>
<exec_depend>only_python</exec_depend>
</package>
41 changes: 40 additions & 1 deletion test/test_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def do_build_package(package_path, work_path) -> None:
'-c', str(cr_dir),
'-o', str(output_dir),
'-d', str(build_dir),
'-u', '..',
])
logger.info(f'*** Building package(s) at {package_path} with options {options}')

Expand Down Expand Up @@ -183,7 +184,8 @@ def test_minimum_package(session_dir):
]
excludes = [
'classes and structs', # only found in C++ projects
'links', # only found if urls defined
'links', # only found if urls defined,
'execution dependencies of this package', # only in meta packages
]
file_includes = [
'search.html',
Expand Down Expand Up @@ -296,3 +298,40 @@ def test_basic_cpp(session_dir):
generated = pathlib.Path(DATAPATH / PKG_NAME / 'doc' / 'generated')
assert not generated.exists(), \
'Building should not create a "generated" directory in package/doc'


def test_meta_package(session_dir):
"""Tests a meta package."""
PKG_NAME = 'meta_package'

do_build_package(DATAPATH / PKG_NAME, session_dir)

includes = [
'execution dependencies of this package',
'only_python',
]
do_test_package(PKG_NAME, session_dir, includes=includes)


def test_do_show_dep(session_dir):
"""Tests rosdoc2.yaml with show_exec_dep=true."""
PKG_NAME = 'do_show_dep'

do_build_package(DATAPATH / PKG_NAME, session_dir)

includes = [
'execution dependencies of this package',
]
do_test_package(PKG_NAME, session_dir, includes=includes)


def test_dont_show_dep(session_dir):
"""Tests rosdoc2.yaml with show_exec_dep=false."""
PKG_NAME = 'dont_show_dep'

do_build_package(DATAPATH / PKG_NAME, session_dir)

excludes = [
'execution dependencies of this package',
]
do_test_package(PKG_NAME, session_dir, excludes=excludes)