-
Notifications
You must be signed in to change notification settings - Fork 10
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
Add support for python-only projects #28
Add support for python-only projects #28
Conversation
Pinging @clalancette and @wjwwood for a review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about this mixed
setting. What I was imagining is a default behavior for ament_cmake
(+ doxygen/exhale/breathe, - sphinx-apidoc), a different one for ament_python
(- doxygen/exhale/breathe, + sphinx-apidoc), and nothing special for all other package build types, but any of them could manually enable/disable things.
So if an ament_cmake
package wanted to build python API docs too, then they would just enable that explicitly in the rosdoc2_settings
dict, rather than change their type to mixed
.
I can see the advantage to more "configuration templates", but it just feels like overkill at the moment, since the 90% case will be either ament_cmake
with only C/C++ or ament_python
with only Python. Everyone else in the meantime would need some special configurations, but if we see a common pattern emerging, then we could add a new "doc build type". As it stands, do you know of any packages that would select mixed
right now?
Another thing to consider is packages that generate messages, but since we're not building first at the moment, that's kind of depending on that. We may have to change the logic more when that happens because right now all packages that have messages need to be ament_cmake
but also will generate Python code for those messages. But again, I think we should defer that concern for now.
Yeah, agreed on that. The other problem with 'mixed' is that if we add another documentation type (say for |
It seems like the
The only such package I can think of off the top of my head is
By "enable that explicitly", do you mean there should be keys |
Regardless of the |
I've dropped the I've also patched up the toctree entries to distinguish between Python/C++ API headings in e43f3ab, just a small QOL thing. Thoughts? |
2bbdc87
to
d159bec
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've left a few minor things to fix up. Mostly I want to make sure that this will continue to work if a new documentation type is added.
Separately, I tried running this against 'launch', and it did indeed work (which is great). But I got quite a few errors when running, of the form:
WARNING: autodoc: failed to import module 'substitutions.this_launch_file' from module 'launch'; the following exception was raised:
No module named 'launch'
08eed57
to
ef8840e
Compare
Thank you for the review again @clalancette, I've committed some of the requested changes and addressed the feedback in commits e188b2d through ef8840e. On the parallel discussion about running against the Short snippet of the warnings from running
|
I was going to suggest this a while ago but got caught up in a review too. It's in the sphinx-autodoc examples that you may need to add the local module directories to the |
Here's what's changed since the latest round of feedback:
Yes, you're right. As I said in #28 (comment), I wrongly assumed the
The solution I've settled on is:
Thoughts about the solution? I could be wrong about my assessment of I believe the PR has addressed most of the feedback provided so far. Thoughts? |
In c6a6595, the `enable_exhale` and `enable_breathe` options were evaluated only if the build type was `ament_cmake` or `cmake`. Following the suggestion in ros-infrastructure#28 (comment), this commit reverts that change, and modifies the behavior such that the values of `enable_exhale` and `enable_breathe` are always checked. The only difference now is that previously, the default value for these settings was `True`. Now, the default is determined by what the build type is and what the `always_run_doxygen` setting has been set to. Essentially, this commit allows users to explicitly enable `enable_exhale` or `enable_breathe` and have those extensions invoked regardless of the build type. Signed-off-by: Abrar Rahman Protyasha <[email protected]>
One important thing we are going to have to keep in mind with this change is the buildfarm. In particular, the current rosdoc2 jobs do not install dependencies or source the ROS environment while building the documentation. In order for this to work, we are going to have to change the buildfarm to do both of those things, otherwise the whole |
I don't think anything will have to be changed in the buildfarm for |
Yeah, my hope is that autodoc just needs to include python modules that are local to the package, but I haven't tested that. All the rest of what you mentioned makes sense to me @aprotyas. I'll do another code review. |
Related to my last comment, the exec() line to include the user e.g. if you do things like https://docs.readthedocs.io/en/stable/guides/adding-custom-css.html. |
This pull request has been mentioned on ROS Discourse. There might be relevant details there: https://discourse.ros.org/t/ros-2-tsc-meeting-minutes-2021-08-19/22008/1 |
This pull request has been mentioned on ROS Discourse. There might be relevant details there: https://discourse.ros.org/t/ros-2-tsc-meeting-minutes-2021-9-16/22372/1 |
This pull request has been mentioned on ROS Discourse. There might be relevant details there: https://discourse.ros.org/t/ros-2-tsc-meeting-minutes-2021-10-28/22947/1 |
That's a great example of something that could either be deferred to the first time it is used, or put into a function, to avoid the issue. For example, it could be this instead: _xml_cache_path = None
def _get_xml_cache_path():
global _xml_cache_path
if _xml_cache_path is None:
_xml_cache_path = urllib.parse.urljoin(
'file:',
urllib.request.pathname2url(
os.path.join(
ament_index_python.get_package_share_directory('sros2'),
'xml_cache',
'xhtml-cache.xml'
)
)
)
return _xml_cache_path So I think mocking is ok, but we just need to fix the issues that are coming up. Long term we could avoid that when we have full builds, but we don't have that right now. So I'd say add back the mocking and fix these issues maybe. |
I've thought of this approach, but this pushes the problem to users, i.e. if we can't build sros2/launch_ros/pkg_foo documentation with rosdoc2, let's see if there are ways to address that in sros2/launch_ros/pkg_foo. Each package in question needs to come up with a specific fix to its "avoid side effects because my dependencies may be mocked" issue. I don't know if we want to do that, especially because we can already afford full builds (they work for both ament_cmake and ament_python packages) |
As @clalancette said, this PR really needs to get landed and issues dealt with in followup. That being said, in the issue of mocking imports, I'm not sure what "# Note: For a user who is running rosdoc2 in an environment where everything they need for their package is already installed, the issue can be fixed in rosdoc2 by importing the modules in conf.py. That is, modify import importlib
for item in autodoc_mock_imports:
try:
importlib.import_module(item)
except:
pass Or alternatively just stop doing the mock. This would allow rosdoc2 to run successfully locally, but then fail when run in an infrastructure environment that produces common documentation. You could always install modules when running rodoc2, but that could be always slow. Perhaps you could add a runtime option to rosdoc2 to install modules prior to running that would be used in the infrastructure setting. Anyway this discussion belongs in a separate issue after this patch has landed. |
b529001
to
f791805
Compare
Signed-off-by: Abrar Rahman Protyasha <[email protected]>
Signed-off-by: Abrar Rahman Protyasha <[email protected]>
f791805
to
4a26f06
Compare
Your interpretation is correct, and my comment there is wrong - I retracted it in 56a7908.
I think this recommendation is reasonable for packages that can actually be imported. From 56a7908: pkgs_to_mock = []
import importlib
for exec_depend in {exec_depends}:
try:
importlib.import_module(exec_depend)
except ImportError:
pkgs_to_mock.append(exec_depend)
autodoc_mock_imports = pkgs_to_mock I'm not fully clear on rosdoc2's expectations regarding the presence of package dependencies on the system, so I haven't dropped mocking outright. Note that the Again, let's defer that conversation to after this PR has landed. @clalancette I think this PR is now ready to land. I've tested that the package builds to completion with launch, launch_testing, launch_pytest, launch_xml, launch_yaml, launch_ros, ros2cli, ros2launch, sros2. I've also checked that rosdoc2 builds for C/C++ packages like rclcpp, rcpputils, rcl, rmw behave the same as before. |
Signed-off-by: Abrar Rahman Protyasha <[email protected]>
What will it take to get this landed? I'd like to do some work on rosdoc2, but I really cannot make progress as long as this PR is outstanding. |
This PR is ready to land from my end too. |
Why is this still open? Can this be merged already? Really appreciate it, thank you. |
I think it's best to copy the 5 files changed and implement the fix locally. That way you do not have to wait for the ROS overlords to finally decide to bless aprotyas great work. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@clalancette I had a chance to test this PR against launch_ros/ros2launch
which is an ament_python
package and rclpy
which is an ament_cmake
package with python APIs to document.
With rclpy
, I had to add a rosdoc2.yaml along with a <rosdoc2>
export tag in the package.xml. The yaml explictly disables doxygen
generation which will execute by default else. However another issue exists with such packages where the sphinx_builder
script will assume doxygen was invoked given the logic introduced here. As a result, it attempts to invoke breathe
and exhale
which will result in an error. That rosdoc2_settings
dict is defined in the same script and it seems like the default entries do not get overwritten/updated by the key-values specified in the rosdoc2.yaml
. So in the end to generate the doc for this pkg I had to explictly set enable_breathe
and enable_exhale
to False
within the script. Also tested using the conf.py
file already in rclpy
by providing a sphinx_sourcedir
arg in the rosdoc2.yaml
file.
I think it should be possible to update that rosdoc2_settings
dict with values from the rosdoc2.yaml
either by injecting suitable entires into the template_variables from the BuildContext
or by updating the implementation of generate_package_toc_entry.
I'm happy to work on this in a follow up PR if we want to merge this first.
Just as an update on the current status here: After discussion, we discovered that generation here is only working because @Yadunund had sourced the workspace before building. While that is one path forward, as it stands the way we generate documentation is in a standalone way. Thus, this PR needs more work to be able to generate standalone, otherwise we get lots of errors like:
|
A few months ago, I did a bit of work on rosdoc2. My repo at https://github.com/rkent/rosdoc2 explored various approaches. I wanted to start to incorporate things in the main rosdoc2. But no progress could be made until the current patch is landed. Requests from several of us to get it landed went unanswered. So I lost interest, and have since moved on to other projects. One of the last things that I did was a branch that added a basic unit test framework, rkent/add-tests, which was to be my suggestion of the minimum changes before suggesting some more radical changes. As part of that, I fixed some obvious issues that the tests revealed, including the issue in @clalancette's comment. This commit seemed to make the issue go away: Essentially the fix that I proposed was to add this line to the default conf.py: sys.path.insert(0, os.path.abspath(os.path.join('{package_src_directory}', '..'))) So, where to go from here? My preference would be to land @aprotyas's patch as-is, and fix issues in subsequent patches. There are other issues with the patch, but it is hard to address them with the current patch unlanded behind a 100 comment thread. It would be much easier to address them with smaller patches, backed up by a basic unit test framework like rkent/add-tests. IIRC rosdoc2 is hardly used in production (has that changed?) so the downsides of just getting it landed are minimal. What this patch really needs is for someone with the power to review and land patches to either land this patch as-is, or specify the minimum needed along with a commitment to review and land in a timely fashion. |
This pull request has been mentioned on ROS Discourse. There might be relevant details there: https://discourse.ros.org/t/ros-2-tsc-meeting-minutes-2023-02-16/29927/1 |
@rkent I can understand your frustration. Just want to point out that Having said that, i'm keen to get My plan is to do one final check that the proposed changes do not break any documentation generation of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Will be opening a follow-up PR with some other changes.
This pull request has been mentioned on ROS Discourse. There might be relevant details there: https://discourse.ros.org/t/growing-issue-with-ros-documentation/36075/48 |
Previously,
rosdoc2
would not generate any documentation for projects without doxygen - more concretely, projects with theament_python
build type - as reported in #19.This PR attempts to resolve that issue. In offline discussions with @clalancette and @wjwwood, we decided that
rosdoc2
can exhibit different behavior for different build types. See this comment for an outline of said behaviors.Specifically, this PR:
build_type
configuration option, which defaults to thebuild_type
obtained from the package.xml file. The set of availablebuild_type
s is [ament_cmake
,cmake
,ament_python
].doxygen_builder
andbreathe
/exhale
extensions forament_python
build types: For this build type,doxygen
does not need to be invoked whatsoever. Similarly, thebreathe
/exhale
extensions tosphinx
need not be registered since there is nodoxygen
-generated tag file to process.toctree
entries for the defaultindex.rst
specific to each build type.python_source
configuration option. This option is represented as a path relative to the package'spackage.xml
file, and should really only be used for packages that do not follow the standard Python package layout. This defaults to[package_name]
.sphinx-apidoc
tool forament_python
build types so that documentation for Python modules can be automatically generated beforesphinx-build
is invoked.Signed-off-by: Abrar Rahman Protyasha [email protected]