From 7946324eb09da2891b7b34b76fb72564728b5744 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Wed, 15 May 2024 16:40:05 -0500 Subject: [PATCH 01/51] Build documentation using Sphinx Signed-off-by: Addisu Z. Taddese --- README.md | 27 ++- _static/css/gazebo.css | 110 ++++++++++++ _static/images/logos/gazebo_horz_neg.svg | 110 ++++++++++++ _static/images/logos/gazebo_horz_pos.svg | 136 ++++++++++++++ _templates/fuel_app_link.html | 1 + _templates/gz-navbar-nav.html | 9 + _templates/gz-sidebar-nav.html | 15 ++ _templates/gz-version-switcher.html | 4 + _templates/sections/header.html | 18 ++ build_multiversion.py | 218 +++++++++++++++++++++++ conf.py | 156 ++++++++++++++++ contributing.md | 23 --- dome/install_osx_src.md | 2 +- dome/sensors.md | 4 +- dome/web_visualization.md | 2 +- get_started.md | 2 +- harmonic/install_windows_src.md | 4 +- harmonic/sensors.md | 10 +- release.md | 6 + release_instructions.md | 2 +- releasing/bump_major.md | 3 + releasing/release_repositories.md | 3 + releasing/versioning_pre_nightly.md | 6 +- ros_installation.md | 6 +- tutorials.yaml | 8 - 25 files changed, 832 insertions(+), 53 deletions(-) create mode 100644 _static/css/gazebo.css create mode 100644 _static/images/logos/gazebo_horz_neg.svg create mode 100644 _static/images/logos/gazebo_horz_pos.svg create mode 100644 _templates/fuel_app_link.html create mode 100644 _templates/gz-navbar-nav.html create mode 100644 _templates/gz-sidebar-nav.html create mode 100644 _templates/gz-version-switcher.html create mode 100644 _templates/sections/header.html create mode 100644 build_multiversion.py create mode 100644 conf.py delete mode 100644 tutorials.yaml diff --git a/README.md b/README.md index 076158701..34caaa758 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,30 @@ found under the `API Reference` section of [https://gazebosim.org/docs](https:// ## Main docs -The documentation in this repository is updated whenever the -[gazebosim-web-backend](https://github.com/gazebo-web/gazebosim-web-backend), -is deployed. The gazebosim-web-backend webserver maintains a clone of this repository, and serves the markdown pages to https://gazebosim.org/docs. +The documentation in this repository is built using [Sphinx](https://www.sphinx-doc.org/). +To build, run: + +```bash +python3 build_multiversion.py +``` + +This will build all the documentation for all versions of Gazebo. +You can preview the result locally by running an HTTP server on +the output directory `.build`. For example: + +```bash +python3 -m http.server 8000 -d .build + +``` + +This will serve the website on + +For quicker iteration, you can build the documentation for a subset +of Gazebo versions. To build `garden` and `harmonic`: + +```bash +python3 build_multiversion.py --release garden harmonic +``` ## Library docs diff --git a/_static/css/gazebo.css b/_static/css/gazebo.css new file mode 100644 index 000000000..6bcf607c8 --- /dev/null +++ b/_static/css/gazebo.css @@ -0,0 +1,110 @@ +html { + --pst-font-family-base: Roboto, var(--pst-font-family-base-system); + --pst-font-size-base: 14px; +} + +html[data-theme="light"] { + --gz-color-doc-header: #4fc3f7; + --gz-color-doc-header-text: #fff; + --pst-color-primary: #0277bd; + --gz-color-primary-sidebar: #f8f9fa; +} + +html[data-theme="dark"] { + --gz-color-doc-header: rgb(15 23 36 / 30%); + --gz-color-doc-header-text: #fff; + --pst-color-primary: #0277bd; + --gz-color-primary-sidebar: #1a1c1e; + --pst-color-background: #131416; +} + +a { + text-decoration: none; +} + +pre { + border: none; +} +.bd-main .bd-content .bd-article-container { + max-width: 160em; +} + +.bd-page-width { + max-width: 100%; +} + +.bd-sidebar { + max-width: 20em; +} + +.sidebar-primary-items__end { + display: none; +} + +.bd-links__title { + display: none; +} + +.navbar-nav .nav-item { + letter-spacing: normal; + text-transform: uppercase; + font-size: 16px; + text-decoration: none; + outline: 0; + transition: 0.5s; + font-weight: 400; + color: #6e6e6e; + border-bottom: 1px solid rgba(0, 0, 0, 0); +} +.navbar-nav li a { + margin-right: 20px; +} + +.bd-header .navbar-header-items { + padding-left: 5em; +} + +.nav-link.nav-external:after { + display: none; +} + +.doc-heading { + width: 100%; + background-color: var(--gz-color-doc-header); + color: var(--gz-color-doc-header-text); + height: 120px; +} + +.banner { + align-items: center; + padding: 20px 40px; + place-content: center space-between; + height: 100%; +} + +header.navbar { + display: block; +} + +.bd-sidebar-primary { + max-height: calc(100vh - var(--pst-header-height) + 120px); + top: calc(var(--pst-header-height) + 120px); + background-color: var(--gz-color-primary-sidebar); +} + +.bd-sidebar-secondary { + max-height: calc(100vh - var(--pst-header-height) + 120px); + top: calc(var(--pst-header-height) + 120px); +} + +.gz-version-switcher { + display: flex; +} +button.btn.version-switcher__button { + color: var(--gz-color-doc-header-text); + border-color: var(--gz-color-doc-header-text); +} + +.navbar-brand img { + height: 84px; +} diff --git a/_static/images/logos/gazebo_horz_neg.svg b/_static/images/logos/gazebo_horz_neg.svg new file mode 100644 index 000000000..1b0aaab8d --- /dev/null +++ b/_static/images/logos/gazebo_horz_neg.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/_static/images/logos/gazebo_horz_pos.svg b/_static/images/logos/gazebo_horz_pos.svg new file mode 100644 index 000000000..c3f296ee8 --- /dev/null +++ b/_static/images/logos/gazebo_horz_pos.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_templates/fuel_app_link.html b/_templates/fuel_app_link.html new file mode 100644 index 000000000..5e9c34e13 --- /dev/null +++ b/_templates/fuel_app_link.html @@ -0,0 +1 @@ +APP diff --git a/_templates/gz-navbar-nav.html b/_templates/gz-navbar-nav.html new file mode 100644 index 000000000..f6a52a75f --- /dev/null +++ b/_templates/gz-navbar-nav.html @@ -0,0 +1,9 @@ + + diff --git a/_templates/gz-sidebar-nav.html b/_templates/gz-sidebar-nav.html new file mode 100644 index 000000000..e72632d85 --- /dev/null +++ b/_templates/gz-sidebar-nav.html @@ -0,0 +1,15 @@ + diff --git a/_templates/gz-version-switcher.html b/_templates/gz-version-switcher.html new file mode 100644 index 000000000..580819022 --- /dev/null +++ b/_templates/gz-version-switcher.html @@ -0,0 +1,4 @@ +
+ Release: +{%- include 'version-switcher.html' -%} +
diff --git a/_templates/sections/header.html b/_templates/sections/header.html new file mode 100644 index 000000000..faf2497f6 --- /dev/null +++ b/_templates/sections/header.html @@ -0,0 +1,18 @@ +{% include "!sections/header.html" %} + +
+ +
diff --git a/build_multiversion.py b/build_multiversion.py new file mode 100644 index 000000000..387520cfb --- /dev/null +++ b/build_multiversion.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2024 Open Source Robotics Foundation +# +# 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. + +from pathlib import Path +from sphinx.cmd.build import main as sphinx_main +import argparse +import os +import copy +import sys +import yaml +import shutil +import json + +additional_shared_directories = ["images", "releasing"] + + +def _combine_nav(common_nav, release_nav): + combined = copy.deepcopy(common_nav) + # Release are added after 'get_started' + for i, item in enumerate(release_nav): + combined.insert(i + 1, item) + return combined + + +def copy_pages(pages, root_src_dir, dst): + for page in pages: + full_dst = Path(dst) / page["file"] + if full_dst.parent != dst: + full_dst.parent.mkdir(parents=True, exist_ok=True) + + shutil.copy2(root_src_dir / page["file"], full_dst) + if "children" in page: + copy_pages(page["children"], root_src_dir, dst) + + +def generate_sources(gz_nav_yaml, root_src_dir, tmp_dir, gz_release): + + if not gz_release: + raise RuntimeError("gz_release not provided") + # Copy release-specific directory + version_src_dir = Path(root_src_dir) / gz_release + + matching_release = [ + release for release in gz_nav_yaml["releases"] if release["name"] == gz_release + ] + if not matching_release: + raise RuntimeError( + f"Provided gz_release '{gz_release}' not registered in `index.yaml`" + ) + elif len(matching_release) > 1: + raise RuntimeError(f"More than one releases named '{gz_release}' found.") + + release_info = matching_release[0] + + tmp_dir.mkdir(exist_ok=True) + version_tmp_dir = tmp_dir / gz_release + + shutil.copytree(version_src_dir, version_tmp_dir, dirs_exist_ok=True) + for dir in ["_static", "_templates"]: + shutil.copytree(root_src_dir / dir, version_tmp_dir / dir, dirs_exist_ok=True) + + shutil.copy2(root_src_dir / "conf.py", version_tmp_dir) + + for dir in additional_shared_directories: + shutil.copytree(root_src_dir / dir, version_tmp_dir / dir, dirs_exist_ok=True) + + copy_pages(gz_nav_yaml["pages"], root_src_dir, version_tmp_dir) + + # Write switcher.json file + switcher = [] + for release in gz_nav_yaml["releases"]: + name = release["name"].capitalize() + if release["eol"]: + name += " (EOL)" + elif release["lts"]: + name += " (LTS)" + + switcher.append( + { + "name": name, + "version": release["name"], + "url": f"/docs/{release['name']}", + } + ) + + static_dir = version_tmp_dir / "_static" + static_dir.mkdir(exist_ok=True) + json.dump(switcher, open(static_dir / "switcher.json", "w")) + + def handle_file_url_rename(file_path, file_url): + computed_url, ext = os.path.splitext(file_path) + print("renames:", file_path, file_url) + if file_url != computed_url: + new_path = file_url + ext + # If the file url is inside a directory, we want the new path to end up in the same directory + print("Moving", version_tmp_dir / file_path, version_tmp_dir / new_path) + shutil.move(version_tmp_dir / file_path, version_tmp_dir / new_path) + return new_path + return file_path + + toc_directives = ["{toctree}", ":hidden:", ":maxdepth: 1", ":titlesonly:"] + + with open(version_tmp_dir / "index.yaml") as f: + version_nav_yaml = yaml.safe_load(f) + combined_nav = _combine_nav(gz_nav_yaml["pages"], version_nav_yaml["pages"]) + + nav_md = [] + # TODO(azeey) Make this recursive so multiple levels of + # 'children' can be supported. + for page in combined_nav: + file_url = page["name"] + file_path = page["file"] + + children = page.get("children") + nav_md.append(f"{page['title']} <{page['name']}>") + new_file_path = handle_file_url_rename(file_path, file_url) + + if children: + child_md = [] + for child in children: + file_url = child["name"] + file_path = child["file"] + handle_file_url_rename(file_path, file_url) + child_md.append(f"{child['title']} <{file_url}>") + + with open(version_tmp_dir / new_file_path, "a") as ind_f: + ind_f.write("```") + ind_f.write("\n".join(toc_directives) + "\n") + ind_f.writelines("\n".join(child_md) + "\n") + ind_f.write("```\n") + + library_reference_nav = "library_reference_nav" + libraries = release_info["libraries"] + if libraries: + nav_md.append(library_reference_nav) + # Add Library Reference + with open(version_tmp_dir / f"{library_reference_nav}.md", "w") as ind_f: + ind_f.write("# Library Reference\n\n") + ind_f.write("```") + ind_f.write("{toctree}\n") + for library in libraries: + ind_f.write( + f"{library['name']} \n" + ) + ind_f.write("```\n\n") + + with open(version_tmp_dir / "index.md", "w") as ind_f: + ind_f.write( + """--- +myst: + html_meta: + "http-equiv=refresh": "0; url=getstarted" +--- +""" + ) + ind_f.write("# Index\n\n") + ind_f.write("```") + ind_f.write("\n".join(toc_directives) + "\n") + ind_f.writelines("\n".join(nav_md) + "\n") + ind_f.write("```\n\n") + + +def main(argv=None): + # We will assume that this file is in the same directory as documentation sources and conf.py files. + parser = argparse.ArgumentParser() + parser.add_argument( + "-r", + "--releases", + metavar="GZ_RELEASES", + nargs="*", + help="Names of releases to build. Builds all known releases if empty.", + ) + args, unknown_args = parser.parse_known_args(argv) + + src_dir = Path(__file__).parent + index_yaml = src_dir / "index.yaml" + assert index_yaml.exists() + + with open(index_yaml) as top_index_file: + gz_nav_yaml = yaml.safe_load(top_index_file) + + if not args.releases: + args.releases = [release["name"] for release in gz_nav_yaml["releases"]] + + tmp_dir = src_dir / ".tmp" + for release in args.releases: + generate_sources(gz_nav_yaml, src_dir, tmp_dir, release) + build_dir = src_dir / ".build" / "docs" / release + sphinx_args = [ + "-b", + "dirhtml", + f"{tmp_dir/release}", + f"{build_dir}", + "-D", + f"gz_release={release}", + "-D", + f"gz_root_index_file={index_yaml}", + *unknown_args, + ] + print(f"sphinx_args: {sphinx_args}") + + sphinx_main(sphinx_args) + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/conf.py b/conf.py new file mode 100644 index 000000000..2ff4a3450 --- /dev/null +++ b/conf.py @@ -0,0 +1,156 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2024 Open Source Robotics Foundation +# +# 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. + +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information +import os +from pathlib import Path +import yaml + + +from sphinx.application import Sphinx +from sphinx.config import Config + +project = "Gazebo" +copyright = "2024, Open Robotics" +author = "Gazebo Team" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "myst_parser", + "sphinx_design", + "sphinx_copybutton", + "sphinx_multiversion", + # 'sphinx_sitemap', +] + +templates_path = ["_templates"] + +exclude_patterns = [ + "build", + "tmp", + "venv", + "conf.py", + "tools", + "_templates", + "Makefile", + "make.bat", + "README.md", + ".git", +] + +source_suffix = [ + ".md", +] + +myst_heading_anchors = 4 + +myst_enable_extensions = [ + "amsmath", + "attrs_inline", + "colon_fence", + "deflist", + "dollarmath", + "fieldlist", + "html_admonition", + "html_image", + "linkify", + "replacements", + "smartquotes", + "strikethrough", + "substitution", + "tasklist", +] + +# TODO(azeey) Setting this to true hides a lot of broken links. Consider using +# the `attrs_inline` myst extension and handle external links case by case +# instead of globally. +# myst_all_links_external = True + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "pydata_sphinx_theme" +html_static_path = ["_static"] +html_style = "css/gazebo.css" +html_theme_options = { + "header_links_before_dropdown": 4, + # "use_edit_page_button": True, + "show_toc_level": 1, + "navigation_with_keys": False, + "show_prev_next": False, + "footer_start": [], + "footer_end": [], + "secondary_sidebar_items": ["page-toc", "edit-this-page"], + "navbar_align": "left", + "navbar_center": ["gz-navbar-nav"], + "navbar_end": ["navbar-icon-links", "theme-switcher", "fuel_app_link"], + "pygment_light_style": "sphinx", + "pygment_dark_style": "monokai", + "logo": { + "image_light": "_static/images/logos/gazebo_horz_pos.svg", + "image_dark": "_static/images/logos/gazebo_horz_neg.svg", + }, + "check_switcher": False, +} + +html_sidebars = {"**": ["gz-sidebar-nav"]} +html_baseurl = os.environ.get( + "SPHINX_HTML_BASE_URL", "http://localhost:8000/docs/latest/" +) + + +def load_releases(index_file): + with open(index_file) as top_index_file: + gz_nav_yaml = yaml.safe_load(top_index_file) + + return dict([(release["name"], release) for release in gz_nav_yaml["releases"]]) + + +def config_init(app: Sphinx, config: Config): + if not config.gz_release: + raise RuntimeError("gz_release not provided") + config.release = config.gz_release # type: ignore + config.version = config.gz_release # type: ignore + + # We've disabled "check_switcher" since it doesn't play well with our directory structure. + # So we check for the existence of switcher.json here + # + assert Path(f"{app.srcdir}/_static/switcher.json").exists() + config.html_theme_options["switcher"] = { + "json_url": f"docs/{config.gz_release}/_static/switcher.json", + "version_match": config.gz_release, + } + + try: + releases = load_releases(config.gz_root_index_file) + app.config.html_context["release_info"] = releases[config.gz_release] + except KeyError as e: + print(e) + raise RuntimeError( + f"Provided gz_release '{config.gz_release}' not registered in `index.yaml`" + ) + +def setup(app: Sphinx): + app.add_config_value("gz_release", "", rebuild="env", types=[str]) + app.add_config_value("gz_root_index_file", "", rebuild="env", types=[str]) + app.connect("config-inited", config_init) diff --git a/contributing.md b/contributing.md index b7c3c4d5e..0c5459a25 100644 --- a/contributing.md +++ b/contributing.md @@ -8,29 +8,6 @@ Organization](https://github.com/gazebosim) on GitHub. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. -#### Table of Contents - -[Code of Conduct](https://gazebosim.org/docs/all/contributing#code-of-conduct) - -[Project Design](https://gazebosim.org/docs/all/contributing#project-design) - - * [Repository List](https://gazebosim.org/docs/all/contributing#repository-list) - -[How to Contribute](https://gazebosim.org/docs/all/contributing#how-to-contribute) - - * [Reporting Bugs](https://gazebosim.org/docs/all/contributing#reporting-bugs) - * [Suggesting Enhancements](https://gazebosim.org/docs/all/contributing#suggesting-enhancements) - * [Contributing Code](https://gazebosim.org/docs/all/contributing#contributing-code) - * [Tracking Progress](https://gazebosim.org/docs/all/contributing#tracking-progress) - -[Writing Tests](https://gazebosim.org/docs/all/contributing#writing-tests) - - * [Test Coverage](https://gazebosim.org/docs/all/contributing#test-coverage) - -[Styleguides](https://gazebosim.org/docs/all/contributing#style-guides) - -[Appendix](https://gazebosim.org/docs/all/contributing#appendix) - ## Code of Conduct This project and everyone participating in it is governed by the [Gazebo diff --git a/dome/install_osx_src.md b/dome/install_osx_src.md index ceaa16d48..163d3dc34 100644 --- a/dome/install_osx_src.md +++ b/dome/install_osx_src.md @@ -122,7 +122,7 @@ If you want to compile Ignition Libraries in MacOS Catalina (10.15) you will nee Create a file called `intern.patch` with the following content: -```patch +```diff --- intern.h 2019-12-16 18:17:08.000000000 +0100 +++ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Ruby.framework/Headers/ruby/ruby/intern.h @@ -14,6 +14,10 @@ diff --git a/dome/sensors.md b/dome/sensors.md index 31ab5597e..159cdf555 100644 --- a/dome/sensors.md +++ b/dome/sensors.md @@ -362,14 +362,14 @@ Inside the main we subscribe to the `lidar` topic, and wait until the node is sh Download the [CMakeLists.txt](https://github.com/ignitionrobotics/docs/blob/master/dome/tutorials/sensors/CMakeLists.txt), and in the same folder of `lidar_node` create `build/` directory: -```{.sh} +```sh mkdir build cd build ``` Run cmake and build the code: -```{.sh} +```sh cmake .. make lidar_node ``` diff --git a/dome/web_visualization.md b/dome/web_visualization.md index 97239a74e..4cd1a1c01 100644 --- a/dome/web_visualization.md +++ b/dome/web_visualization.md @@ -62,7 +62,7 @@ matching key using an "auth" call on the websocket. If the ` **NOTE** > As Gazebo GUI is not yet working, running `gz sim` will not work. You can run only the server with -> ```cmd +> ```bat > gz sim -s -v > ``` @@ -152,7 +152,7 @@ page to start using Gazebo! > If your username contains spaces (which is quite common on Windows), you will probably get errors > saying `Invalid partition name [Computer:My User With Spaces]`. Fix this by changing `GZ_PARTITION` > to something else: -> ```cmd +> ```bat > set GZ_PARTITION=test > ``` > Remember to set the same partition in all other consoles. diff --git a/harmonic/sensors.md b/harmonic/sensors.md index 24f3ea514..e95829827 100644 --- a/harmonic/sensors.md +++ b/harmonic/sensors.md @@ -382,14 +382,14 @@ Inside the main we subscribe to the `lidar` topic, and wait until the node is sh Download the [CMakeLists.txt](https://github.com/gazebosim/docs/blob/master/harmonic/tutorials/sensors/CMakeLists.txt), and in the same folder of `lidar_node` create `build/` directory: -```{.sh} +```sh mkdir build cd build ``` Run cmake and build the code: -```{.sh} +```sh cmake .. make lidar_node ``` @@ -398,13 +398,13 @@ make lidar_node Run the node from terminal 1: -```{.sh} +```sh ./build/lidar_node ``` Run the world from terminal 2: -```{.sh} +```sh gz sim sensor_tutorial.sdf ``` @@ -433,7 +433,7 @@ The first command is `gz sim sensor_tutorial.sdf` which launches the world. And the second command is `./build/lidar_node` which runs the `lidar_node`. Save the file as `sensor_launch.gzlaunch`, and then run it using the following command: -```{.sh} +```sh gz launch sensor_launch.gzlaunch ``` diff --git a/release.md b/release.md index 9286e877f..9d66bcd3e 100644 --- a/release.md +++ b/release.md @@ -233,4 +233,10 @@ During the Gazebo Garden development period, this packaage was to use stable and nightly binaries. It is customary to use nightly binaries for all unreleased package versions. +```{toctree} +:hidden: +:maxdepth: 1 +:titlesonly: +releasing/versioning_pre_nightly +``` diff --git a/release_instructions.md b/release_instructions.md index d157fd074..927d75624 100644 --- a/release_instructions.md +++ b/release_instructions.md @@ -64,7 +64,7 @@ features), patch number (patches and bugfixes). **Bumping major number** of the version implies some work to have the [metadata](#metadata-for-releasing) updated correctly. There is a [dedicated -document](releasing/bump_major) that you should go through before continuing to work through the steps in this +document](releasing/bump_major.md) that you should go through before continuing to work through the steps in this document. 1. To update the upstream version a local checkout of the Gz library is diff --git a/releasing/bump_major.md b/releasing/bump_major.md index fea81aad1..8b3750747 100644 --- a/releasing/bump_major.md +++ b/releasing/bump_major.md @@ -1,3 +1,6 @@ +--- +orphan: true +--- # Bump major versions > WARNING: this document is no more than a list of steps. Check with the infra-team diff --git a/releasing/release_repositories.md b/releasing/release_repositories.md index bddbdf3d1..52b7157bc 100644 --- a/releasing/release_repositories.md +++ b/releasing/release_repositories.md @@ -1,3 +1,6 @@ +--- +orphan: true +--- # Release repositories > TODO: the document needs to be completed with real information. The points diff --git a/releasing/versioning_pre_nightly.md b/releasing/versioning_pre_nightly.md index 80e7b36fc..ed9040989 100644 --- a/releasing/versioning_pre_nightly.md +++ b/releasing/versioning_pre_nightly.md @@ -1,4 +1,4 @@ -## Debian/Ubuntu versioning in nightly and prerelease binaries +# Debian/Ubuntu versioning in nightly and prerelease binaries Binary packages produced for prerelease and nightly builds have some particularities to establish the priority among them nicely. @@ -17,7 +17,7 @@ this precedence, the nighlty version uses the trick of setting the version to `{X-1.99.99}` (i.e: if the version to release is `9.0.0`, the nightlies used before the version will use `8.99.99`). -### Version schemes +## Version schemes **Prerelease** versioning scheme: `{upcoming_version}~pre{prerelease_version}` @@ -39,7 +39,7 @@ the version will use `8.99.99`). * `nightly_revision`: revision number to apply to the nightly. It is also used to generate a new nightly using the same date timestamp. -### Versions when mixing stable, prerelease and nightly +## Versions when mixing stable, prerelease and nightly Which version has priority when using prerelease and stable repositories? diff --git a/ros_installation.md b/ros_installation.md index d9612237d..62f2068ff 100644 --- a/ros_installation.md +++ b/ros_installation.md @@ -92,9 +92,9 @@ versions that have the same major number (`gz-sim7_7.0.0`, `gz-sim7_7.1.0`, `gz-sim7_7.0.1`, ...) are binary compatible and thus interchangeable with a given ROS distro. -## Installing Gazebo +### Installing Gazebo -### Gazebo Packages for Ubuntu +#### Gazebo Packages for Ubuntu The easiest way of installing Gazebo on Ubuntu is to use binary packages. There are two main repositories that host Gazebo simulator and Gazebo libraries: one @@ -248,7 +248,7 @@ Getting the latest versions of the Gazebo libraries and simulator is as easy as installing the [`osrfoundation.org` repository](https://gazebosim.org/docs/latest/install_ubuntu_src#install-dependencies) together with the ROS repository. Updates should be fully compatible. -## FAQ +### FAQ #### I am not using ROS at all, which version should I use? diff --git a/tutorials.yaml b/tutorials.yaml deleted file mode 100644 index 72ec21e96..000000000 --- a/tutorials.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# This file is an index of the pages to display on the documentation website -# (https://gazebosim.org/tutorials). The order of the pages in this file -# is reflected on the website's left sidebar. - -releases: - - citadel - - blueprint - - acropolis From a6afd1490c6faf06457de9b70e45b4c51d2a8093 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Wed, 15 May 2024 16:40:05 -0500 Subject: [PATCH 02/51] Build documentation using Sphinx Signed-off-by: Addisu Z. Taddese --- README.md | 42 ++++- _static/css/gazebo.css | 110 ++++++++++++ _static/images/logos/gazebo_horz_neg.svg | 110 ++++++++++++ _static/images/logos/gazebo_horz_pos.svg | 136 ++++++++++++++ _templates/fuel_app_link.html | 1 + _templates/gz-navbar-nav.html | 9 + _templates/gz-sidebar-nav.html | 15 ++ _templates/gz-version-switcher.html | 4 + _templates/sections/header.html | 18 ++ build_multiversion.py | 218 +++++++++++++++++++++++ conf.py | 141 +++++++++++++++ contributing.md | 23 --- dome/install_osx_src.md | 2 +- dome/sensors.md | 4 +- dome/web_visualization.md | 2 +- get_started.md | 2 +- harmonic/install_windows_src.md | 4 +- harmonic/sensors.md | 10 +- release.md | 6 + release_instructions.md | 2 +- releasing/bump_major.md | 3 + releasing/release_repositories.md | 3 + releasing/versioning_pre_nightly.md | 6 +- requirements.txt | 5 + ros_installation.md | 6 +- tutorials.yaml | 8 - 26 files changed, 837 insertions(+), 53 deletions(-) create mode 100644 _static/css/gazebo.css create mode 100644 _static/images/logos/gazebo_horz_neg.svg create mode 100644 _static/images/logos/gazebo_horz_pos.svg create mode 100644 _templates/fuel_app_link.html create mode 100644 _templates/gz-navbar-nav.html create mode 100644 _templates/gz-sidebar-nav.html create mode 100644 _templates/gz-version-switcher.html create mode 100644 _templates/sections/header.html create mode 100644 build_multiversion.py create mode 100644 conf.py create mode 100644 requirements.txt delete mode 100644 tutorials.yaml diff --git a/README.md b/README.md index 076158701..731656c61 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,45 @@ found under the `API Reference` section of [https://gazebosim.org/docs](https:// ## Main docs -The documentation in this repository is updated whenever the -[gazebosim-web-backend](https://github.com/gazebo-web/gazebosim-web-backend), -is deployed. The gazebosim-web-backend webserver maintains a clone of this repository, and serves the markdown pages to https://gazebosim.org/docs. +The documentation in this repository is built using [Sphinx](https://www.sphinx-doc.org/). +To build, you need to install the following: + +* python virtualenv + +Create the virtual env and activate it: + +```bash +python3 -m venv .venv +source .venv/bin/activate +``` + +Then install the necessary dependencies: + +```bash +pip install -r requirements.txt +``` + +```bash +python3 build_multiversion.py +``` + +This will build all the documentation for all versions of Gazebo. +You can preview the result locally by running an HTTP server on +the output directory `.build`. For example: + +```bash +python3 -m http.server 8000 -d .build + +``` + +This will serve the website on + +For quicker iteration, you can build the documentation for a subset +of Gazebo versions. To build `garden` and `harmonic`: + +```bash +python3 build_multiversion.py --release garden harmonic +``` ## Library docs diff --git a/_static/css/gazebo.css b/_static/css/gazebo.css new file mode 100644 index 000000000..6bcf607c8 --- /dev/null +++ b/_static/css/gazebo.css @@ -0,0 +1,110 @@ +html { + --pst-font-family-base: Roboto, var(--pst-font-family-base-system); + --pst-font-size-base: 14px; +} + +html[data-theme="light"] { + --gz-color-doc-header: #4fc3f7; + --gz-color-doc-header-text: #fff; + --pst-color-primary: #0277bd; + --gz-color-primary-sidebar: #f8f9fa; +} + +html[data-theme="dark"] { + --gz-color-doc-header: rgb(15 23 36 / 30%); + --gz-color-doc-header-text: #fff; + --pst-color-primary: #0277bd; + --gz-color-primary-sidebar: #1a1c1e; + --pst-color-background: #131416; +} + +a { + text-decoration: none; +} + +pre { + border: none; +} +.bd-main .bd-content .bd-article-container { + max-width: 160em; +} + +.bd-page-width { + max-width: 100%; +} + +.bd-sidebar { + max-width: 20em; +} + +.sidebar-primary-items__end { + display: none; +} + +.bd-links__title { + display: none; +} + +.navbar-nav .nav-item { + letter-spacing: normal; + text-transform: uppercase; + font-size: 16px; + text-decoration: none; + outline: 0; + transition: 0.5s; + font-weight: 400; + color: #6e6e6e; + border-bottom: 1px solid rgba(0, 0, 0, 0); +} +.navbar-nav li a { + margin-right: 20px; +} + +.bd-header .navbar-header-items { + padding-left: 5em; +} + +.nav-link.nav-external:after { + display: none; +} + +.doc-heading { + width: 100%; + background-color: var(--gz-color-doc-header); + color: var(--gz-color-doc-header-text); + height: 120px; +} + +.banner { + align-items: center; + padding: 20px 40px; + place-content: center space-between; + height: 100%; +} + +header.navbar { + display: block; +} + +.bd-sidebar-primary { + max-height: calc(100vh - var(--pst-header-height) + 120px); + top: calc(var(--pst-header-height) + 120px); + background-color: var(--gz-color-primary-sidebar); +} + +.bd-sidebar-secondary { + max-height: calc(100vh - var(--pst-header-height) + 120px); + top: calc(var(--pst-header-height) + 120px); +} + +.gz-version-switcher { + display: flex; +} +button.btn.version-switcher__button { + color: var(--gz-color-doc-header-text); + border-color: var(--gz-color-doc-header-text); +} + +.navbar-brand img { + height: 84px; +} diff --git a/_static/images/logos/gazebo_horz_neg.svg b/_static/images/logos/gazebo_horz_neg.svg new file mode 100644 index 000000000..1b0aaab8d --- /dev/null +++ b/_static/images/logos/gazebo_horz_neg.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/_static/images/logos/gazebo_horz_pos.svg b/_static/images/logos/gazebo_horz_pos.svg new file mode 100644 index 000000000..c3f296ee8 --- /dev/null +++ b/_static/images/logos/gazebo_horz_pos.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_templates/fuel_app_link.html b/_templates/fuel_app_link.html new file mode 100644 index 000000000..5e9c34e13 --- /dev/null +++ b/_templates/fuel_app_link.html @@ -0,0 +1 @@ +APP diff --git a/_templates/gz-navbar-nav.html b/_templates/gz-navbar-nav.html new file mode 100644 index 000000000..f6a52a75f --- /dev/null +++ b/_templates/gz-navbar-nav.html @@ -0,0 +1,9 @@ + + diff --git a/_templates/gz-sidebar-nav.html b/_templates/gz-sidebar-nav.html new file mode 100644 index 000000000..e72632d85 --- /dev/null +++ b/_templates/gz-sidebar-nav.html @@ -0,0 +1,15 @@ + diff --git a/_templates/gz-version-switcher.html b/_templates/gz-version-switcher.html new file mode 100644 index 000000000..580819022 --- /dev/null +++ b/_templates/gz-version-switcher.html @@ -0,0 +1,4 @@ +
+ Release: +{%- include 'version-switcher.html' -%} +
diff --git a/_templates/sections/header.html b/_templates/sections/header.html new file mode 100644 index 000000000..faf2497f6 --- /dev/null +++ b/_templates/sections/header.html @@ -0,0 +1,18 @@ +{% include "!sections/header.html" %} + +
+ +
diff --git a/build_multiversion.py b/build_multiversion.py new file mode 100644 index 000000000..387520cfb --- /dev/null +++ b/build_multiversion.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2024 Open Source Robotics Foundation +# +# 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. + +from pathlib import Path +from sphinx.cmd.build import main as sphinx_main +import argparse +import os +import copy +import sys +import yaml +import shutil +import json + +additional_shared_directories = ["images", "releasing"] + + +def _combine_nav(common_nav, release_nav): + combined = copy.deepcopy(common_nav) + # Release are added after 'get_started' + for i, item in enumerate(release_nav): + combined.insert(i + 1, item) + return combined + + +def copy_pages(pages, root_src_dir, dst): + for page in pages: + full_dst = Path(dst) / page["file"] + if full_dst.parent != dst: + full_dst.parent.mkdir(parents=True, exist_ok=True) + + shutil.copy2(root_src_dir / page["file"], full_dst) + if "children" in page: + copy_pages(page["children"], root_src_dir, dst) + + +def generate_sources(gz_nav_yaml, root_src_dir, tmp_dir, gz_release): + + if not gz_release: + raise RuntimeError("gz_release not provided") + # Copy release-specific directory + version_src_dir = Path(root_src_dir) / gz_release + + matching_release = [ + release for release in gz_nav_yaml["releases"] if release["name"] == gz_release + ] + if not matching_release: + raise RuntimeError( + f"Provided gz_release '{gz_release}' not registered in `index.yaml`" + ) + elif len(matching_release) > 1: + raise RuntimeError(f"More than one releases named '{gz_release}' found.") + + release_info = matching_release[0] + + tmp_dir.mkdir(exist_ok=True) + version_tmp_dir = tmp_dir / gz_release + + shutil.copytree(version_src_dir, version_tmp_dir, dirs_exist_ok=True) + for dir in ["_static", "_templates"]: + shutil.copytree(root_src_dir / dir, version_tmp_dir / dir, dirs_exist_ok=True) + + shutil.copy2(root_src_dir / "conf.py", version_tmp_dir) + + for dir in additional_shared_directories: + shutil.copytree(root_src_dir / dir, version_tmp_dir / dir, dirs_exist_ok=True) + + copy_pages(gz_nav_yaml["pages"], root_src_dir, version_tmp_dir) + + # Write switcher.json file + switcher = [] + for release in gz_nav_yaml["releases"]: + name = release["name"].capitalize() + if release["eol"]: + name += " (EOL)" + elif release["lts"]: + name += " (LTS)" + + switcher.append( + { + "name": name, + "version": release["name"], + "url": f"/docs/{release['name']}", + } + ) + + static_dir = version_tmp_dir / "_static" + static_dir.mkdir(exist_ok=True) + json.dump(switcher, open(static_dir / "switcher.json", "w")) + + def handle_file_url_rename(file_path, file_url): + computed_url, ext = os.path.splitext(file_path) + print("renames:", file_path, file_url) + if file_url != computed_url: + new_path = file_url + ext + # If the file url is inside a directory, we want the new path to end up in the same directory + print("Moving", version_tmp_dir / file_path, version_tmp_dir / new_path) + shutil.move(version_tmp_dir / file_path, version_tmp_dir / new_path) + return new_path + return file_path + + toc_directives = ["{toctree}", ":hidden:", ":maxdepth: 1", ":titlesonly:"] + + with open(version_tmp_dir / "index.yaml") as f: + version_nav_yaml = yaml.safe_load(f) + combined_nav = _combine_nav(gz_nav_yaml["pages"], version_nav_yaml["pages"]) + + nav_md = [] + # TODO(azeey) Make this recursive so multiple levels of + # 'children' can be supported. + for page in combined_nav: + file_url = page["name"] + file_path = page["file"] + + children = page.get("children") + nav_md.append(f"{page['title']} <{page['name']}>") + new_file_path = handle_file_url_rename(file_path, file_url) + + if children: + child_md = [] + for child in children: + file_url = child["name"] + file_path = child["file"] + handle_file_url_rename(file_path, file_url) + child_md.append(f"{child['title']} <{file_url}>") + + with open(version_tmp_dir / new_file_path, "a") as ind_f: + ind_f.write("```") + ind_f.write("\n".join(toc_directives) + "\n") + ind_f.writelines("\n".join(child_md) + "\n") + ind_f.write("```\n") + + library_reference_nav = "library_reference_nav" + libraries = release_info["libraries"] + if libraries: + nav_md.append(library_reference_nav) + # Add Library Reference + with open(version_tmp_dir / f"{library_reference_nav}.md", "w") as ind_f: + ind_f.write("# Library Reference\n\n") + ind_f.write("```") + ind_f.write("{toctree}\n") + for library in libraries: + ind_f.write( + f"{library['name']} \n" + ) + ind_f.write("```\n\n") + + with open(version_tmp_dir / "index.md", "w") as ind_f: + ind_f.write( + """--- +myst: + html_meta: + "http-equiv=refresh": "0; url=getstarted" +--- +""" + ) + ind_f.write("# Index\n\n") + ind_f.write("```") + ind_f.write("\n".join(toc_directives) + "\n") + ind_f.writelines("\n".join(nav_md) + "\n") + ind_f.write("```\n\n") + + +def main(argv=None): + # We will assume that this file is in the same directory as documentation sources and conf.py files. + parser = argparse.ArgumentParser() + parser.add_argument( + "-r", + "--releases", + metavar="GZ_RELEASES", + nargs="*", + help="Names of releases to build. Builds all known releases if empty.", + ) + args, unknown_args = parser.parse_known_args(argv) + + src_dir = Path(__file__).parent + index_yaml = src_dir / "index.yaml" + assert index_yaml.exists() + + with open(index_yaml) as top_index_file: + gz_nav_yaml = yaml.safe_load(top_index_file) + + if not args.releases: + args.releases = [release["name"] for release in gz_nav_yaml["releases"]] + + tmp_dir = src_dir / ".tmp" + for release in args.releases: + generate_sources(gz_nav_yaml, src_dir, tmp_dir, release) + build_dir = src_dir / ".build" / "docs" / release + sphinx_args = [ + "-b", + "dirhtml", + f"{tmp_dir/release}", + f"{build_dir}", + "-D", + f"gz_release={release}", + "-D", + f"gz_root_index_file={index_yaml}", + *unknown_args, + ] + print(f"sphinx_args: {sphinx_args}") + + sphinx_main(sphinx_args) + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/conf.py b/conf.py new file mode 100644 index 000000000..e27c06ee4 --- /dev/null +++ b/conf.py @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2024 Open Source Robotics Foundation +# +# 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. + +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information +import os +from pathlib import Path +import yaml + + +from sphinx.application import Sphinx +from sphinx.config import Config + +project = "Gazebo" +copyright = "2024, Open Robotics" +author = "Gazebo Team" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "myst_parser", + "sphinx_copybutton", + # 'sphinx_sitemap', +] + +templates_path = ["_templates"] + +source_suffix = [ + ".md", +] + +myst_heading_anchors = 4 + +myst_enable_extensions = [ + "amsmath", + "attrs_inline", + "colon_fence", + "deflist", + "dollarmath", + "fieldlist", + "html_admonition", + "html_image", + "linkify", + "replacements", + "smartquotes", + "strikethrough", + "substitution", + "tasklist", +] + +# TODO(azeey) Setting this to true hides a lot of broken links. Consider using +# the `attrs_inline` myst extension and handle external links case by case +# instead of globally. +# myst_all_links_external = True + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "pydata_sphinx_theme" +html_static_path = ["_static"] +html_style = "css/gazebo.css" +html_theme_options = { + "header_links_before_dropdown": 4, + # "use_edit_page_button": True, + "show_toc_level": 1, + "navigation_with_keys": False, + "show_prev_next": False, + "footer_start": [], + "footer_end": [], + "secondary_sidebar_items": ["page-toc", "edit-this-page"], + "navbar_align": "left", + "navbar_center": ["gz-navbar-nav"], + "navbar_end": ["navbar-icon-links", "theme-switcher", "fuel_app_link"], + "pygment_light_style": "sphinx", + "pygment_dark_style": "monokai", + "logo": { + "image_light": "_static/images/logos/gazebo_horz_pos.svg", + "image_dark": "_static/images/logos/gazebo_horz_neg.svg", + }, + "check_switcher": False, +} + +html_sidebars = {"**": ["gz-sidebar-nav"]} +html_baseurl = os.environ.get( + "SPHINX_HTML_BASE_URL", "http://localhost:8000/docs/latest/" +) + + +def load_releases(index_file): + with open(index_file) as top_index_file: + gz_nav_yaml = yaml.safe_load(top_index_file) + + return dict([(release["name"], release) for release in gz_nav_yaml["releases"]]) + + +def config_init(app: Sphinx, config: Config): + if not config.gz_release: + raise RuntimeError("gz_release not provided") + config.release = config.gz_release # type: ignore + config.version = config.gz_release # type: ignore + + # We've disabled "check_switcher" since it doesn't play well with our directory structure. + # So we check for the existence of switcher.json here + # + assert Path(f"{app.srcdir}/_static/switcher.json").exists() + config.html_theme_options["switcher"] = { + "json_url": f"docs/{config.gz_release}/_static/switcher.json", + "version_match": config.gz_release, + } + + try: + releases = load_releases(config.gz_root_index_file) + app.config.html_context["release_info"] = releases[config.gz_release] + except KeyError as e: + print(e) + raise RuntimeError( + f"Provided gz_release '{config.gz_release}' not registered in `index.yaml`" + ) + +def setup(app: Sphinx): + app.add_config_value("gz_release", "", rebuild="env", types=[str]) + app.add_config_value("gz_root_index_file", "", rebuild="env", types=[str]) + app.connect("config-inited", config_init) diff --git a/contributing.md b/contributing.md index b7c3c4d5e..0c5459a25 100644 --- a/contributing.md +++ b/contributing.md @@ -8,29 +8,6 @@ Organization](https://github.com/gazebosim) on GitHub. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. -#### Table of Contents - -[Code of Conduct](https://gazebosim.org/docs/all/contributing#code-of-conduct) - -[Project Design](https://gazebosim.org/docs/all/contributing#project-design) - - * [Repository List](https://gazebosim.org/docs/all/contributing#repository-list) - -[How to Contribute](https://gazebosim.org/docs/all/contributing#how-to-contribute) - - * [Reporting Bugs](https://gazebosim.org/docs/all/contributing#reporting-bugs) - * [Suggesting Enhancements](https://gazebosim.org/docs/all/contributing#suggesting-enhancements) - * [Contributing Code](https://gazebosim.org/docs/all/contributing#contributing-code) - * [Tracking Progress](https://gazebosim.org/docs/all/contributing#tracking-progress) - -[Writing Tests](https://gazebosim.org/docs/all/contributing#writing-tests) - - * [Test Coverage](https://gazebosim.org/docs/all/contributing#test-coverage) - -[Styleguides](https://gazebosim.org/docs/all/contributing#style-guides) - -[Appendix](https://gazebosim.org/docs/all/contributing#appendix) - ## Code of Conduct This project and everyone participating in it is governed by the [Gazebo diff --git a/dome/install_osx_src.md b/dome/install_osx_src.md index ceaa16d48..163d3dc34 100644 --- a/dome/install_osx_src.md +++ b/dome/install_osx_src.md @@ -122,7 +122,7 @@ If you want to compile Ignition Libraries in MacOS Catalina (10.15) you will nee Create a file called `intern.patch` with the following content: -```patch +```diff --- intern.h 2019-12-16 18:17:08.000000000 +0100 +++ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Ruby.framework/Headers/ruby/ruby/intern.h @@ -14,6 +14,10 @@ diff --git a/dome/sensors.md b/dome/sensors.md index 31ab5597e..159cdf555 100644 --- a/dome/sensors.md +++ b/dome/sensors.md @@ -362,14 +362,14 @@ Inside the main we subscribe to the `lidar` topic, and wait until the node is sh Download the [CMakeLists.txt](https://github.com/ignitionrobotics/docs/blob/master/dome/tutorials/sensors/CMakeLists.txt), and in the same folder of `lidar_node` create `build/` directory: -```{.sh} +```sh mkdir build cd build ``` Run cmake and build the code: -```{.sh} +```sh cmake .. make lidar_node ``` diff --git a/dome/web_visualization.md b/dome/web_visualization.md index 97239a74e..4cd1a1c01 100644 --- a/dome/web_visualization.md +++ b/dome/web_visualization.md @@ -62,7 +62,7 @@ matching key using an "auth" call on the websocket. If the ` **NOTE** > As Gazebo GUI is not yet working, running `gz sim` will not work. You can run only the server with -> ```cmd +> ```bat > gz sim -s -v > ``` @@ -152,7 +152,7 @@ page to start using Gazebo! > If your username contains spaces (which is quite common on Windows), you will probably get errors > saying `Invalid partition name [Computer:My User With Spaces]`. Fix this by changing `GZ_PARTITION` > to something else: -> ```cmd +> ```bat > set GZ_PARTITION=test > ``` > Remember to set the same partition in all other consoles. diff --git a/harmonic/sensors.md b/harmonic/sensors.md index 24f3ea514..e95829827 100644 --- a/harmonic/sensors.md +++ b/harmonic/sensors.md @@ -382,14 +382,14 @@ Inside the main we subscribe to the `lidar` topic, and wait until the node is sh Download the [CMakeLists.txt](https://github.com/gazebosim/docs/blob/master/harmonic/tutorials/sensors/CMakeLists.txt), and in the same folder of `lidar_node` create `build/` directory: -```{.sh} +```sh mkdir build cd build ``` Run cmake and build the code: -```{.sh} +```sh cmake .. make lidar_node ``` @@ -398,13 +398,13 @@ make lidar_node Run the node from terminal 1: -```{.sh} +```sh ./build/lidar_node ``` Run the world from terminal 2: -```{.sh} +```sh gz sim sensor_tutorial.sdf ``` @@ -433,7 +433,7 @@ The first command is `gz sim sensor_tutorial.sdf` which launches the world. And the second command is `./build/lidar_node` which runs the `lidar_node`. Save the file as `sensor_launch.gzlaunch`, and then run it using the following command: -```{.sh} +```sh gz launch sensor_launch.gzlaunch ``` diff --git a/release.md b/release.md index 9286e877f..9d66bcd3e 100644 --- a/release.md +++ b/release.md @@ -233,4 +233,10 @@ During the Gazebo Garden development period, this packaage was to use stable and nightly binaries. It is customary to use nightly binaries for all unreleased package versions. +```{toctree} +:hidden: +:maxdepth: 1 +:titlesonly: +releasing/versioning_pre_nightly +``` diff --git a/release_instructions.md b/release_instructions.md index d157fd074..927d75624 100644 --- a/release_instructions.md +++ b/release_instructions.md @@ -64,7 +64,7 @@ features), patch number (patches and bugfixes). **Bumping major number** of the version implies some work to have the [metadata](#metadata-for-releasing) updated correctly. There is a [dedicated -document](releasing/bump_major) that you should go through before continuing to work through the steps in this +document](releasing/bump_major.md) that you should go through before continuing to work through the steps in this document. 1. To update the upstream version a local checkout of the Gz library is diff --git a/releasing/bump_major.md b/releasing/bump_major.md index fea81aad1..8b3750747 100644 --- a/releasing/bump_major.md +++ b/releasing/bump_major.md @@ -1,3 +1,6 @@ +--- +orphan: true +--- # Bump major versions > WARNING: this document is no more than a list of steps. Check with the infra-team diff --git a/releasing/release_repositories.md b/releasing/release_repositories.md index bddbdf3d1..52b7157bc 100644 --- a/releasing/release_repositories.md +++ b/releasing/release_repositories.md @@ -1,3 +1,6 @@ +--- +orphan: true +--- # Release repositories > TODO: the document needs to be completed with real information. The points diff --git a/releasing/versioning_pre_nightly.md b/releasing/versioning_pre_nightly.md index 80e7b36fc..ed9040989 100644 --- a/releasing/versioning_pre_nightly.md +++ b/releasing/versioning_pre_nightly.md @@ -1,4 +1,4 @@ -## Debian/Ubuntu versioning in nightly and prerelease binaries +# Debian/Ubuntu versioning in nightly and prerelease binaries Binary packages produced for prerelease and nightly builds have some particularities to establish the priority among them nicely. @@ -17,7 +17,7 @@ this precedence, the nighlty version uses the trick of setting the version to `{X-1.99.99}` (i.e: if the version to release is `9.0.0`, the nightlies used before the version will use `8.99.99`). -### Version schemes +## Version schemes **Prerelease** versioning scheme: `{upcoming_version}~pre{prerelease_version}` @@ -39,7 +39,7 @@ the version will use `8.99.99`). * `nightly_revision`: revision number to apply to the nightly. It is also used to generate a new nightly using the same date timestamp. -### Versions when mixing stable, prerelease and nightly +## Versions when mixing stable, prerelease and nightly Which version has priority when using prerelease and stable repositories? diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..7c8aebfbf --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +myst-parser[linkify] +pydata-sphinx-theme +pyyaml +sphinx +sphinx-copybutton diff --git a/ros_installation.md b/ros_installation.md index d9612237d..62f2068ff 100644 --- a/ros_installation.md +++ b/ros_installation.md @@ -92,9 +92,9 @@ versions that have the same major number (`gz-sim7_7.0.0`, `gz-sim7_7.1.0`, `gz-sim7_7.0.1`, ...) are binary compatible and thus interchangeable with a given ROS distro. -## Installing Gazebo +### Installing Gazebo -### Gazebo Packages for Ubuntu +#### Gazebo Packages for Ubuntu The easiest way of installing Gazebo on Ubuntu is to use binary packages. There are two main repositories that host Gazebo simulator and Gazebo libraries: one @@ -248,7 +248,7 @@ Getting the latest versions of the Gazebo libraries and simulator is as easy as installing the [`osrfoundation.org` repository](https://gazebosim.org/docs/latest/install_ubuntu_src#install-dependencies) together with the ROS repository. Updates should be fully compatible. -## FAQ +### FAQ #### I am not using ROS at all, which version should I use? diff --git a/tutorials.yaml b/tutorials.yaml deleted file mode 100644 index 72ec21e96..000000000 --- a/tutorials.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# This file is an index of the pages to display on the documentation website -# (https://gazebosim.org/tutorials). The order of the pages in this file -# is reflected on the website's left sidebar. - -releases: - - citadel - - blueprint - - acropolis From 5f30f9279c5cf0892e61ee68c93bd223da8fd2f3 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Tue, 21 May 2024 17:12:12 -0500 Subject: [PATCH 03/51] Add documentation for Gazebo vendor packages Signed-off-by: Addisu Z. Taddese --- index.yaml | 5 ++ ros2_gz_vendor_pkgs.md | 177 +++++++++++++++++++++++++++++++++++++++++ ros_installation.md | 8 ++ 3 files changed, 190 insertions(+) create mode 100644 ros2_gz_vendor_pkgs.md diff --git a/index.yaml b/index.yaml index 5a736dfd0..84a0d1d4c 100644 --- a/index.yaml +++ b/index.yaml @@ -23,6 +23,11 @@ pages: title: ROS/Gazebo Installation file: ros_installation.md description: Our development plans. + children: + - name: ros2_gz_vendor_pkgs + title: ROS 2 Gazebo Vendor Packages + file: ros2_gz_vendor_pkgs.md + description: Using ROS 2 Gazebo Vendor packages - name: migrating_gazebo_classic_ros2_packages title: Migration from ROS 2 Gazebo Classic file: migrating_gazebo_classic_ros2_packages.md diff --git a/ros2_gz_vendor_pkgs.md b/ros2_gz_vendor_pkgs.md new file mode 100644 index 000000000..b038580e8 --- /dev/null +++ b/ros2_gz_vendor_pkgs.md @@ -0,0 +1,177 @@ +# ROS 2 Gazebo Vendor Packages + +ROS 2 versions prior to Jazzy used Gazebo packages that were available in +upstream Ubuntu. However, due to the package +[update policy of Ubuntu](https://wiki.ubuntu.com/StableReleaseUpdates), the +Gazebo packages on upstream Ubuntu did not receive any updates. Thus, upstream +Ubuntu almost always had older versions of Gazebo than what was available from +the Gazebo package repository (packages.osrfoundation.org). To overcome this, +more up-to-date Gazebo packages were copied to the ROS bootstrap repository +(repos.ros.org) which were then copied to the main ROS package repository +(packages.ros.org). However, the process was error prone and keeping package +versions in sync between the Gazebo and ROS package repositories was difficult +since this was a manual process. + +As of ROS 2 Jazzy, Gazebo is available from the ROS package repository via +vendor packages. A ROS vendor package is a ROS package that provides software +that ROS needs on platforms where it might not be available, or where a +different version than what is available is required [^1]. + +The Gazebo vendor packages provide all of the Gazebo libraries to a given ROS +release. The packages are built in the ROS buildfarm and as part of their build +process, fetch the sources of the underlying Gazebo library and build it. In +addition, the vendor packages provide CMake shims that make it possible to use +CMake targets without version numbers. + +Each release of ROS 2 is paired with a specific release of Gazebo. For ROS 2 +Jazzy, the vendor packages contain Gazebo libraries from the Harmonic release. +For ROS 2 K-turtle (next release), the vendor packages will contain Gazebo +Ionic. This default pairing is found in the +[ROS installation instructions](https://gazebosim.org/docs/harmonic/ros_installation) + +The following is a table of all vendor packages and the underlying Gazebo +library they vendor: + +| Vendor Package | Gazebo Library | +| -------------------------------------------------------------------------------- | ----------------------------------------------------------- | +| [gz_cmake_vendor](https://github.com/gazebo-release/gz_cmake_vendor) | [gz-cmake](https://github.com/gazebosim/gz-cmake) | +| [gz_common_vendor](https://github.com/gazebo-release/gz_common_vendor) | [gz-common](https://github.com/gazebosim/gz-common) | +| [gz_fuel_tools_vendor](https://github.com/gazebo-release/gz_fuel_tools_vendor) | [gz-fuel-tools](https://github.com/gazebosim/gz-fuel-tools) | +| [gz_gui_vendor](https://github.com/gazebo-release/gz_gui_vendor) | [gz-gui](https://github.com/gazebosim/gz-gui) | +| [gz_launch_vendor](https://github.com/gazebo-release/gz_launch_vendor.git) | [gz-launch](https://github.com/gazebosim/gz-launch) | +| [gz_math_vendor](https://github.com/gazebo-release/gz_math_vendor.git) | [gz-math](https://github.com/gazebosim/gz-math) | +| [gz_msgs_vendor](https://github.com/gazebo-release/gz_msgs_vendor.git) | [gz-msgs](https://github.com/gazebosim/gz-msgs) | +| [gz_physics_vendor](https://github.com/gazebo-release/gz_physics_vendor.git) | [gz-physics](https://github.com/gazebosim/gz-physics) | +| [gz_plugin_vendor](https://github.com/gazebo-release/gz_plugin_vendor.git) | [gz-plugin](https://github.com/gazebosim/gz-plugin) | +| [gz_rendering_vendor](https://github.com/gazebo-release/gz_rendering_vendor.git) | [gz-rendering](https://github.com/gazebosim/gz-rendering) | +| [gz_sensors_vendor](https://github.com/gazebo-release/gz_sensors_vendor.git) | [gz-sensors](https://github.com/gazebosim/gz-sensors) | +| [gz_sim_vendor](https://github.com/gazebo-release/gz_sim_vendor.git) | [gz-sim](https://github.com/gazebosim/gz-sim) | +| [gz_tools_vendor](https://github.com/gazebo-release/gz_tools_vendor.git) | [gz-tools](https://github.com/gazebosim/gz-tools) | +| [gz_transport_vendor](https://github.com/gazebo-release/gz_transport_vendor.git) | [gz-transport](https://github.com/gazebosim/gz-transport) | +| [gz_utils_vendor](https://github.com/gazebo-release/gz_utils_vendor.git) | [gz-utils](https://github.com/gazebosim/gz-utils) | +| [sdformat_vendor](https://github.com/gazebo-release/sdformat_vendor.git) | [sdformat](https://github.com/gazebosim/sdformat) | + +In addition to Gazebo libraries, two dependencies of Gazebo are also vendored: + +| Vendor Package | External Library | +| -------------------------------------------------------------------------------- | -------------------------------------------------- | +| [gz_dartsim_vendor](https://github.com/gazebo-release/gz_dartsim_vendor.git) | [dartsim](https://github.com/dartsim/dart) | +| [gz_ogre_next_vendor](https://github.com/gazebo-release/gz_ogre_next_vendor.git) | [ogre-next](https://github.com/OGRECave/ogre-next) | + +**Note:** These two vendor packages are only intended to be consumed by Gazebo. +Use of this vendor package generally (outside of Gazebo) is not recommended as +the underlying library version might change without notice. + +## Using vendor packages in `package.xml` + +To use a Gazebo vendor package in your project, you'll need to add the +appropriate package in your `package.xml`. For example, if you use the Gazebo +libraries `gz-cmake`, `gz-utils` and `gz-math`, the entries in `package.xml` +will be the following + +```xml + ... + gz_cmake_vendor + gz_utils_vendor + gz_math_vendor + ... +``` + +## Using vendor packages in CMake + +To use a Gazebo library provided by a vendor package, you'll need to +`find_package` the vendor package and the underlying Gazebo library. Calling +`find_package` on the vendor package indicates that the project is "buying into" +the CMake shims provided by the vendor package. These shims make it possible to +`find_package` the underlying library and use its CMake targets without +including the version number in the name. Thus, when upgrading to newer versions +of Gazebo, the project `CMakeLists` file would not need to be modified. + +Following the example above, The CMake entry for using `gz-cmake`, `gz-utils` +and `gz-math` will be the following: + +```cmake +find_package(gz_cmake_vendor REQUIRED) +find_package(gz-cmake REQUIRED) +find_package(gz_utils_vendor REQUIRED) +find_package(gz-utils REQUIRED) +find_package(gz_math_vendor REQUIRED) +find_package(gz-math REQUIRED) + +add_executable(test_gz_vendor main.cc) +target_link_libraries(test_gz_vendor PUBLIC gz-math::gz-math gz-utils::gz-utils) +``` + +**Note:** The vendor packages use underscores (`_`) while the Gazebo library +names use dashes (`-`). + +## Using vendor packages with binaries from packages.osrfoundation.org + +If you want to use a new release of Gazebo that is not officially paired with +the release of ROS you are using (e.g. Gazebo Ionic with ROS 2 Jazzy), you can +follow the following steps: + +1. Install the binaries from packages.osrfoundation.org. Make sure to install + the metapackage that includes all library components (e.g. gz-ionic, + gz-harmonic, etc.) +1. Clone the set of vendor packages included in + [gz_vendor.repos](https://gist.github.com/azeey/a94adb591475ea0e613313d3540ca451) + in your workspace using [vcstool](https://github.com/dirk-thomas/vcstool). +1. Checkout the desired branch. The branch names currently track ROS 2 releases. + You'll need to determine the branch based on the + [default pairings](/docs/latest/ros_installation) +1. Add any additional packages you need that also depend on Gazebo, such as + [`ros_gz`](https://github.com/gazebosim/ros_gz) and + [`gz_ros2_control`](https://github.com/ros-controls/gz_ros2_control/) +1. `export GZ_RELAX_VERSION_MATCH=1`. By default, the vendor packages look for + an exact version match of the vendored library to be available in the system. + If the exact version is not found, the sources are fetched and built. This + environment variable causes the vendor package to match just the major + version number. +1. Build the workspace + +## Gazebo library development with vendor packages + +Building the underlying packages from source might be needed when using a Gazebo +release that is not officially paired with the ROS release you are using or when +developing on a Gazebo library in conjunction with another ROS package that uses +Gazebo directly. You can follow these steps to build the vendor packages from +source: + +1. Clone the desired release of the Gazebo libraries into a workspace. You can + use a collection file from + (e.g. + [`collection-harmonic.yaml`](https://github.com/gazebo-tooling/gazebodistro/blob/master/collection-harmonic.yaml)) + with [vcstool](https://github.com/dirk-thomas/vcstool). +1. Clone the set of vendor packages included in + [gz_vendor.repos](https://gist.github.com/azeey/a94adb591475ea0e613313d3540ca451) + in the same workspace using + [vcstool](https://github.com/dirk-thomas/vcstool). +1. Checkout the desired branch. The branch names currently track ROS 2 releases. + You'll need to determine the branch based on the + [official pairings](/docs/latest/ros_installation) +1. Add any additional packages you need that also depend on Gazebo, such as + [`ros_gz`](https://github.com/gazebosim/ros_gz) and + [`gz_ros2_control`](https://github.com/ros-controls/gz_ros2_control/) +1. `export GZ_BUILD_FROM_SOURCE=1`. By default, the vendor packages look for an + exact version match of the vendored library to be available in the system. If + the exact version is not found, the sources are fetched and built. Also, by + default, the vendor packages do not depend directly on the Gazebo libraries + you have in your workspace. Setting this environment variable causes the + vendor package to match just the major version number and add dependencies on + the Gazebo libraries being built from source so that the correct build order + is followed. +1. Build the workspace + +## Known Limitations + +- The vendor packages are currently built with Python bindings disabled + ([issue](https://github.com/gazebo-tooling/gz_vendor/issues/2)) +- `gz_dartsim_vendor` and `gz_ogre_next_vendor` currently always build from + source + ([gz_dartsim_vendor issue](https://github.com/gazebo-release/gz_dartsim_vendor/issues/4), + [gz_ogre_next_vendor issue](https://github.com/gazebo-release/gz_ogre_next_vendor/issues/4)) +- When building Gazebo libraries from source, it is not possible to build some + packages from source and install some packages from binaries. + +[^1]: https://robotics.stackexchange.com/a/93262/31574 diff --git a/ros_installation.md b/ros_installation.md index d9612237d..e5bc4b358 100644 --- a/ros_installation.md +++ b/ros_installation.md @@ -71,6 +71,14 @@ sudo apt-get install ros-${ROS_DISTRO}-ros-gz This command will install the Gazebo libraries recommended for your ROS installation. +### ROS 2 Gazebo Vendor packages + +As of ROS 2 Jazzy, Gazebo is available from the ROS package repository via +vendor packages. If your package directly depends on a Gazebo library, +instead of relying only on `ros_gz`, refer to +[this documentation](ros2_gz_vendor_pkgs) to learn how to use the +Gazebo vendor packages. +
The rest of this document provides more information and other, alternative, installations pathways. We do not recommend the following approaches for new From e3049d5b211619087d6e7c6005d0c777b798470e Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Tue, 7 May 2024 17:51:48 -0500 Subject: [PATCH 04/51] Indicate that Gazebo Fortress is recommended for ROS 2 Humble and Iron users (#437) Signed-off-by: Addisu Z. Taddese --- get_started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/get_started.md b/get_started.md index 8510629ed..bac67148b 100644 --- a/get_started.md +++ b/get_started.md @@ -17,7 +17,7 @@ packages available for the platform to use: |Platform|Gazebo Versions| |---|---| -| Ubuntu 22.04 Jammy | [Gazebo Harmonic](/docs/harmonic/install_ubuntu) (recommended), [Gazebo Garden](/docs/garden/install_ubuntu) and [Gazebo Fortress](/docs/fortress/install_ubuntu) +| Ubuntu 22.04 Jammy | [Gazebo Harmonic](/docs/harmonic/install_ubuntu) (recommended), [Gazebo Garden](/docs/garden/install_ubuntu) and [Gazebo Fortress](/docs/fortress/install_ubuntu) (recommended if using ROS 2 Humble or Iron) | Ubuntu 20.04 Focal | [Gazebo Garden](/docs/garden/install_ubuntu) (recommended), [Gazebo Fortress](/docs/fortress/install_ubuntu) and [Gazebo Citadel](/docs/citadel/install_ubuntu) | Ubuntu 18.04 Bionic | [Gazebo Citadel](/docs/citadel/install_ubuntu) | Mac Ventura | [Gazebo Harmonic](/docs/harmonic/install_osx) (recommended), [Gazebo Garden](/docs/garden/install_osx), [Gazebo Fortress](/docs/fortress/install_osx) and [Gazebo Citadel](/docs/citadel/install_osx) From 10742d56722bf850acf89f09fdd5038b6dfee66f Mon Sep 17 00:00:00 2001 From: Jose Luis Rivero Date: Tue, 14 May 2024 22:32:39 +0200 Subject: [PATCH 05/51] Installing Gazebo11 side by side with new Gazebo Tutorial (#438) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Installing Gazebo11 side by side with new Gazebo Tutorial --------- Signed-off-by: Jose Luis Rivero Co-authored-by: Alejandro Hernández Cordero --- garden/install_ubuntu.md | 5 ++- harmonic/install_ubuntu.md | 7 +++- install_gz11_side_by_side.md | 71 ++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 install_gz11_side_by_side.md diff --git a/garden/install_ubuntu.md b/garden/install_ubuntu.md index 1afcdc371..10360f054 100644 --- a/garden/install_ubuntu.md +++ b/garden/install_ubuntu.md @@ -4,7 +4,10 @@ Garden binaries are provided for Ubuntu Focal and Jammy. The Garden binaries are hosted in the packages.osrfoundation.org repository. To install all of them, the metapackage `gz-garden` can be installed. -**WARNING:** `gz-garden` cannot be installed alongside gazebo-classic (eg. `gazebo11`) since both use the `gz` command line tool. Trying to install `gz-garden` on a system that already has gazebo-classic installed from binaries will cause gazebo-classic and its dependencies to be uninstalled. Currently, the workarounds for this are to install from source or to use Docker [`gazebo-classic`](https://hub.docker.com/_/gazebo) so they are not installed side-by-side on the same system. +**WARNING:** for gazebo-classic (eg. `gazebo11`) users: `gz-garden` cannot be +installed alongside with `gazebo11` by default. To facilitate the migration +this can be done using the instruction detailed in +[Installing Gazebo11 side by side with new Gazebo](/docs/all/install_gz11_side_by_side). First install some necessary tools: diff --git a/harmonic/install_ubuntu.md b/harmonic/install_ubuntu.md index 72391d8b9..134282fb2 100644 --- a/harmonic/install_ubuntu.md +++ b/harmonic/install_ubuntu.md @@ -1,10 +1,13 @@ # Binary Installation on Ubuntu -Harmonic binaries are provided for Ubuntu Jammy (22.04) and Ubuntu 24.04 (when it's released). The +Harmonic binaries are provided for Ubuntu Jammy (22.04) and Ubuntu Noble (24.04). The Harmonic binaries are hosted in the packages.osrfoundation.org repository. To install all of them, the metapackage `gz-harmonic` can be installed. -**WARNING:** `gz-harmonic` cannot be installed alongside gazebo-classic (eg. `gazebo11`) since both use the `gz` command line tool. Trying to install `gz-harmonic` on a system that already has gazebo-classic installed from binaries will cause gazebo-classic and its dependencies to be uninstalled. Currently, the workarounds for this are to install from source or to use Docker [`gazebo-classic`](https://hub.docker.com/_/gazebo) so they are not installed side-by-side on the same system. +*WARNING:** for gazebo-classic (eg. `gazebo11`) users: `gz-harmonic` cannot be +installed alongside with `gazebo11` by default. To facilitate the migration +this can be done using the instruction detailed in +[Installing Gazebo11 side by side with new Gazebo](/docs/all/install_gz11_side_by_side). First install some necessary tools: diff --git a/install_gz11_side_by_side.md b/install_gz11_side_by_side.md new file mode 100644 index 000000000..d4cfdf496 --- /dev/null +++ b/install_gz11_side_by_side.md @@ -0,0 +1,71 @@ +# Installing Gazebo11 side by side with new Gazebo + +## Supported Gazebo versions and Ubuntu platforms for this tutorial + +This tutorial affects the Gazebo Classic users on Ubuntu `Jammy` (latest +Ubuntu release were Gazebo Classic packages supported by the Gazebo team) +that plan on migrating code to new Gazebo `Fortress`, `Garden` or `Harmonic.` + +There is no guarantee that the Gazebo Classic version detailed in this document +will be updated in any case. Please consider the migration to the new Gazebo +as the recommended alternative. + +## General context and migrations to new Gazebo + +New versions of Gazebo can not be installed together with Gazebo Classic +(aka `gazebo11`) since both use the `gz` command line tool. Trying to +install `gz-garden` or `gz-harmonic` from `packages.osrfoundation.org` +on a system that already has gazebo-classic installed from binaries +will cause gazebo-classic and its dependencies to be uninstalled. + +Having a side by side installation of both can make easier the recommended +migration to newer versions of Gazebo. + +## Alternative approach for Gazebo Classic without the gz tool + +A possible workaround could be to use Gazebo Classic without the `gz` +command or with a renamed `gz` command. This can be particularly +interesting since the ROS (Robot Operative System) wrapper known as +`gazebo_ros_pkgs` do not use the `gz` command but the `gzserver` and +`gzclient` commands. + +Not shipping the `gz` command by default in a Gazebo Classic installation +would be a disruptive change for existing users so it should not be hosted in +`packages.osrfoundation.org`. + +## Gazebo11 with a separate gz tool package + +This alterntive approach has been implemented and packages for `jammy` are +hosted in the Open Robotics `gazebo11-gz-cli` PPA: +https://launchpad.net/~openrobotics/+archive/ubuntu/gazebo11-gz-cli + +The PPA contains a `gazebo11` version that ships the `gz` executable in +an independent packages called `gazebo11-gz-cli` while the main `gazebo11` +package has a `gz11` command. Both are really symlinks to `gz-11.x.y`. + +### How the packaging works for the gz command + +The `gazebo11-gz-cli` is a soft dependency on `gazebo11`. It is installed +by default but it will be uninstalled when installing the new Gazebo +packages and the effect is that the `gz` command for Gazebo Classic replaced +by the `gz` tool from new Gazebo. The `gz11` command can be used instead of +the `gz` command to access to the same functionality. + +## Installing the new packaging from the PPA + +From an existing `gazebo11` installation (on `jammy` the Ubuntu official +repositories will install `11.10.2+dfsg-1` version) or a non existing +`gazebo11` installation the steps are the following: + +```bash +sudo add-apt-repository ppa:openrobotics/gazebo11-gz-cli +sudo apt update +sudo apt-get install gazebo11 +``` + +If `gazebo11` was installed before, it will be upgraded to the version in the +PPA. From this point, a new Gazebo installation for `fortress`, `garden` or +`harmonic` can be executed. + +If a new Gazebo installation was installed before, the `gazebo11-gz-cli` package +won't be installed. From 9795585007b9df4db987273dd35d4d33e86b1a36 Mon Sep 17 00:00:00 2001 From: Jose Luis Rivero Date: Wed, 15 May 2024 09:52:15 +0200 Subject: [PATCH 06/51] Minor updates on Noble references (#439) Signed-off-by: Jose Luis Rivero --- harmonic/install.md | 2 +- harmonic/install_ubuntu_src.md | 2 +- ionic/install.md | 2 +- ionic/install_ubuntu.md | 2 +- ionic/install_ubuntu_src.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/harmonic/install.md b/harmonic/install.md index 3f769c930..b91a9bbb5 100644 --- a/harmonic/install.md +++ b/harmonic/install.md @@ -55,7 +55,7 @@ This list may change up to the release date. These are the **officially** supported platforms: * Ubuntu Jammy on amd64 -* Ubuntu 24.04 on amd64 +* Ubuntu Noble on amd64 Platforms supported at **best-effort** include arm architectures, Windows and macOS. See diff --git a/harmonic/install_ubuntu_src.md b/harmonic/install_ubuntu_src.md index 5eb23e2ba..41a8f5c6a 100644 --- a/harmonic/install_ubuntu_src.md +++ b/harmonic/install_ubuntu_src.md @@ -1,6 +1,6 @@ # Source Installation on Ubuntu -These instructions apply to Ubuntu Jammy (22.04) and Ubuntu 24.04. +These instructions apply to Ubuntu Jammy (22.04) and Ubuntu Noble (24.04). ## Install tools diff --git a/ionic/install.md b/ionic/install.md index 9c0952a29..6a6c6f260 100644 --- a/ionic/install.md +++ b/ionic/install.md @@ -55,7 +55,7 @@ This list may change up to the release date. These are the **officially** supported platforms: * Ubuntu Jammy on amd64 -* Ubuntu 24.04 on amd64 +* Ubuntu Noble on amd64 Platforms supported at **best-effort** include arm architectures, Windows and macOS. See diff --git a/ionic/install_ubuntu.md b/ionic/install_ubuntu.md index 8b9039260..bac107503 100644 --- a/ionic/install_ubuntu.md +++ b/ionic/install_ubuntu.md @@ -1,6 +1,6 @@ # Binary Installation on Ubuntu -Ionic binaries are provided for Ubuntu Jammy (22.04) and Ubuntu 24.04 (when it's released). The +Ionic binaries are provided for Ubuntu Jammy (22.04) and Ubuntu Noble (24.04). The Ionic binaries are hosted in the packages.osrfoundation.org repository. To install all of them, the metapackage `gz-ionic` can be installed. diff --git a/ionic/install_ubuntu_src.md b/ionic/install_ubuntu_src.md index 4005b0ea4..974b25616 100644 --- a/ionic/install_ubuntu_src.md +++ b/ionic/install_ubuntu_src.md @@ -1,6 +1,6 @@ # Source Installation on Ubuntu -These instructions apply to Ubuntu Jammy (22.04) and Ubuntu 24.04. +These instructions apply to Ubuntu Jammy (22.04) and Ubuntu Noble (24.04). ## Install tools From 4d2759b09e9c8b00d9102f83402e8843186a0dd7 Mon Sep 17 00:00:00 2001 From: Steve Peters Date: Wed, 15 May 2024 15:31:48 +0200 Subject: [PATCH 07/51] contributing.md: suggest multi-repo features target main (#440) Signed-off-by: Steve Peters --- contributing.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/contributing.md b/contributing.md index 15092bc5d..b7c3c4d5e 100644 --- a/contributing.md +++ b/contributing.md @@ -183,8 +183,14 @@ get acquainted with this development process. take place in your fork. - An important thing to do is create a remote pointing to the [upstream remote repository](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/configuring-a-remote-for-a-fork). This way, you can always check for modifications on the original repository and **always** keep your fork repository up to date. -1. **Choose a base branch.** If your changes will break API or ABI, then - base your new branch off of `main`. If your changes don't break +1. **Choose a base branch.** + - If your changes will break API or ABI, then base your new branch off of `main`. + - If you are making interdependent changes to multiple repositories without + breaking API or ABI, it is also recommended to base your new branches of of `main` + to simplify automated testing of the changes and the review process. Your + changes may be backported to an existing release once all the changes + have been merged. + - If your changes don't break API/ABI and you would like them to be released to an existing release with major version `N`, then use branch `gz-N` as the base. From 51b6f908c6478122fd8efeac4e30d1f323856812 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Wed, 15 May 2024 16:40:05 -0500 Subject: [PATCH 08/51] Build documentation using Sphinx Signed-off-by: Addisu Z. Taddese --- README.md | 42 ++++- _static/css/gazebo.css | 110 ++++++++++++ _static/images/logos/gazebo_horz_neg.svg | 110 ++++++++++++ _static/images/logos/gazebo_horz_pos.svg | 136 ++++++++++++++ _templates/fuel_app_link.html | 1 + _templates/gz-navbar-nav.html | 9 + _templates/gz-sidebar-nav.html | 15 ++ _templates/gz-version-switcher.html | 4 + _templates/sections/header.html | 18 ++ build_multiversion.py | 218 +++++++++++++++++++++++ conf.py | 141 +++++++++++++++ contributing.md | 23 --- dome/install_osx_src.md | 2 +- dome/sensors.md | 4 +- dome/web_visualization.md | 2 +- get_started.md | 2 +- harmonic/install_windows_src.md | 4 +- harmonic/sensors.md | 10 +- release.md | 6 + release_instructions.md | 2 +- releasing/bump_major.md | 3 + releasing/release_repositories.md | 3 + releasing/versioning_pre_nightly.md | 6 +- requirements.txt | 5 + ros_installation.md | 6 +- tutorials.yaml | 8 - 26 files changed, 837 insertions(+), 53 deletions(-) create mode 100644 _static/css/gazebo.css create mode 100644 _static/images/logos/gazebo_horz_neg.svg create mode 100644 _static/images/logos/gazebo_horz_pos.svg create mode 100644 _templates/fuel_app_link.html create mode 100644 _templates/gz-navbar-nav.html create mode 100644 _templates/gz-sidebar-nav.html create mode 100644 _templates/gz-version-switcher.html create mode 100644 _templates/sections/header.html create mode 100644 build_multiversion.py create mode 100644 conf.py create mode 100644 requirements.txt delete mode 100644 tutorials.yaml diff --git a/README.md b/README.md index 076158701..731656c61 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,45 @@ found under the `API Reference` section of [https://gazebosim.org/docs](https:// ## Main docs -The documentation in this repository is updated whenever the -[gazebosim-web-backend](https://github.com/gazebo-web/gazebosim-web-backend), -is deployed. The gazebosim-web-backend webserver maintains a clone of this repository, and serves the markdown pages to https://gazebosim.org/docs. +The documentation in this repository is built using [Sphinx](https://www.sphinx-doc.org/). +To build, you need to install the following: + +* python virtualenv + +Create the virtual env and activate it: + +```bash +python3 -m venv .venv +source .venv/bin/activate +``` + +Then install the necessary dependencies: + +```bash +pip install -r requirements.txt +``` + +```bash +python3 build_multiversion.py +``` + +This will build all the documentation for all versions of Gazebo. +You can preview the result locally by running an HTTP server on +the output directory `.build`. For example: + +```bash +python3 -m http.server 8000 -d .build + +``` + +This will serve the website on + +For quicker iteration, you can build the documentation for a subset +of Gazebo versions. To build `garden` and `harmonic`: + +```bash +python3 build_multiversion.py --release garden harmonic +``` ## Library docs diff --git a/_static/css/gazebo.css b/_static/css/gazebo.css new file mode 100644 index 000000000..6bcf607c8 --- /dev/null +++ b/_static/css/gazebo.css @@ -0,0 +1,110 @@ +html { + --pst-font-family-base: Roboto, var(--pst-font-family-base-system); + --pst-font-size-base: 14px; +} + +html[data-theme="light"] { + --gz-color-doc-header: #4fc3f7; + --gz-color-doc-header-text: #fff; + --pst-color-primary: #0277bd; + --gz-color-primary-sidebar: #f8f9fa; +} + +html[data-theme="dark"] { + --gz-color-doc-header: rgb(15 23 36 / 30%); + --gz-color-doc-header-text: #fff; + --pst-color-primary: #0277bd; + --gz-color-primary-sidebar: #1a1c1e; + --pst-color-background: #131416; +} + +a { + text-decoration: none; +} + +pre { + border: none; +} +.bd-main .bd-content .bd-article-container { + max-width: 160em; +} + +.bd-page-width { + max-width: 100%; +} + +.bd-sidebar { + max-width: 20em; +} + +.sidebar-primary-items__end { + display: none; +} + +.bd-links__title { + display: none; +} + +.navbar-nav .nav-item { + letter-spacing: normal; + text-transform: uppercase; + font-size: 16px; + text-decoration: none; + outline: 0; + transition: 0.5s; + font-weight: 400; + color: #6e6e6e; + border-bottom: 1px solid rgba(0, 0, 0, 0); +} +.navbar-nav li a { + margin-right: 20px; +} + +.bd-header .navbar-header-items { + padding-left: 5em; +} + +.nav-link.nav-external:after { + display: none; +} + +.doc-heading { + width: 100%; + background-color: var(--gz-color-doc-header); + color: var(--gz-color-doc-header-text); + height: 120px; +} + +.banner { + align-items: center; + padding: 20px 40px; + place-content: center space-between; + height: 100%; +} + +header.navbar { + display: block; +} + +.bd-sidebar-primary { + max-height: calc(100vh - var(--pst-header-height) + 120px); + top: calc(var(--pst-header-height) + 120px); + background-color: var(--gz-color-primary-sidebar); +} + +.bd-sidebar-secondary { + max-height: calc(100vh - var(--pst-header-height) + 120px); + top: calc(var(--pst-header-height) + 120px); +} + +.gz-version-switcher { + display: flex; +} +button.btn.version-switcher__button { + color: var(--gz-color-doc-header-text); + border-color: var(--gz-color-doc-header-text); +} + +.navbar-brand img { + height: 84px; +} diff --git a/_static/images/logos/gazebo_horz_neg.svg b/_static/images/logos/gazebo_horz_neg.svg new file mode 100644 index 000000000..1b0aaab8d --- /dev/null +++ b/_static/images/logos/gazebo_horz_neg.svg @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/_static/images/logos/gazebo_horz_pos.svg b/_static/images/logos/gazebo_horz_pos.svg new file mode 100644 index 000000000..c3f296ee8 --- /dev/null +++ b/_static/images/logos/gazebo_horz_pos.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_templates/fuel_app_link.html b/_templates/fuel_app_link.html new file mode 100644 index 000000000..5e9c34e13 --- /dev/null +++ b/_templates/fuel_app_link.html @@ -0,0 +1 @@ +APP diff --git a/_templates/gz-navbar-nav.html b/_templates/gz-navbar-nav.html new file mode 100644 index 000000000..f6a52a75f --- /dev/null +++ b/_templates/gz-navbar-nav.html @@ -0,0 +1,9 @@ + + diff --git a/_templates/gz-sidebar-nav.html b/_templates/gz-sidebar-nav.html new file mode 100644 index 000000000..e72632d85 --- /dev/null +++ b/_templates/gz-sidebar-nav.html @@ -0,0 +1,15 @@ + diff --git a/_templates/gz-version-switcher.html b/_templates/gz-version-switcher.html new file mode 100644 index 000000000..580819022 --- /dev/null +++ b/_templates/gz-version-switcher.html @@ -0,0 +1,4 @@ +
+ Release: +{%- include 'version-switcher.html' -%} +
diff --git a/_templates/sections/header.html b/_templates/sections/header.html new file mode 100644 index 000000000..faf2497f6 --- /dev/null +++ b/_templates/sections/header.html @@ -0,0 +1,18 @@ +{% include "!sections/header.html" %} + +
+ +
diff --git a/build_multiversion.py b/build_multiversion.py new file mode 100644 index 000000000..387520cfb --- /dev/null +++ b/build_multiversion.py @@ -0,0 +1,218 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2024 Open Source Robotics Foundation +# +# 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. + +from pathlib import Path +from sphinx.cmd.build import main as sphinx_main +import argparse +import os +import copy +import sys +import yaml +import shutil +import json + +additional_shared_directories = ["images", "releasing"] + + +def _combine_nav(common_nav, release_nav): + combined = copy.deepcopy(common_nav) + # Release are added after 'get_started' + for i, item in enumerate(release_nav): + combined.insert(i + 1, item) + return combined + + +def copy_pages(pages, root_src_dir, dst): + for page in pages: + full_dst = Path(dst) / page["file"] + if full_dst.parent != dst: + full_dst.parent.mkdir(parents=True, exist_ok=True) + + shutil.copy2(root_src_dir / page["file"], full_dst) + if "children" in page: + copy_pages(page["children"], root_src_dir, dst) + + +def generate_sources(gz_nav_yaml, root_src_dir, tmp_dir, gz_release): + + if not gz_release: + raise RuntimeError("gz_release not provided") + # Copy release-specific directory + version_src_dir = Path(root_src_dir) / gz_release + + matching_release = [ + release for release in gz_nav_yaml["releases"] if release["name"] == gz_release + ] + if not matching_release: + raise RuntimeError( + f"Provided gz_release '{gz_release}' not registered in `index.yaml`" + ) + elif len(matching_release) > 1: + raise RuntimeError(f"More than one releases named '{gz_release}' found.") + + release_info = matching_release[0] + + tmp_dir.mkdir(exist_ok=True) + version_tmp_dir = tmp_dir / gz_release + + shutil.copytree(version_src_dir, version_tmp_dir, dirs_exist_ok=True) + for dir in ["_static", "_templates"]: + shutil.copytree(root_src_dir / dir, version_tmp_dir / dir, dirs_exist_ok=True) + + shutil.copy2(root_src_dir / "conf.py", version_tmp_dir) + + for dir in additional_shared_directories: + shutil.copytree(root_src_dir / dir, version_tmp_dir / dir, dirs_exist_ok=True) + + copy_pages(gz_nav_yaml["pages"], root_src_dir, version_tmp_dir) + + # Write switcher.json file + switcher = [] + for release in gz_nav_yaml["releases"]: + name = release["name"].capitalize() + if release["eol"]: + name += " (EOL)" + elif release["lts"]: + name += " (LTS)" + + switcher.append( + { + "name": name, + "version": release["name"], + "url": f"/docs/{release['name']}", + } + ) + + static_dir = version_tmp_dir / "_static" + static_dir.mkdir(exist_ok=True) + json.dump(switcher, open(static_dir / "switcher.json", "w")) + + def handle_file_url_rename(file_path, file_url): + computed_url, ext = os.path.splitext(file_path) + print("renames:", file_path, file_url) + if file_url != computed_url: + new_path = file_url + ext + # If the file url is inside a directory, we want the new path to end up in the same directory + print("Moving", version_tmp_dir / file_path, version_tmp_dir / new_path) + shutil.move(version_tmp_dir / file_path, version_tmp_dir / new_path) + return new_path + return file_path + + toc_directives = ["{toctree}", ":hidden:", ":maxdepth: 1", ":titlesonly:"] + + with open(version_tmp_dir / "index.yaml") as f: + version_nav_yaml = yaml.safe_load(f) + combined_nav = _combine_nav(gz_nav_yaml["pages"], version_nav_yaml["pages"]) + + nav_md = [] + # TODO(azeey) Make this recursive so multiple levels of + # 'children' can be supported. + for page in combined_nav: + file_url = page["name"] + file_path = page["file"] + + children = page.get("children") + nav_md.append(f"{page['title']} <{page['name']}>") + new_file_path = handle_file_url_rename(file_path, file_url) + + if children: + child_md = [] + for child in children: + file_url = child["name"] + file_path = child["file"] + handle_file_url_rename(file_path, file_url) + child_md.append(f"{child['title']} <{file_url}>") + + with open(version_tmp_dir / new_file_path, "a") as ind_f: + ind_f.write("```") + ind_f.write("\n".join(toc_directives) + "\n") + ind_f.writelines("\n".join(child_md) + "\n") + ind_f.write("```\n") + + library_reference_nav = "library_reference_nav" + libraries = release_info["libraries"] + if libraries: + nav_md.append(library_reference_nav) + # Add Library Reference + with open(version_tmp_dir / f"{library_reference_nav}.md", "w") as ind_f: + ind_f.write("# Library Reference\n\n") + ind_f.write("```") + ind_f.write("{toctree}\n") + for library in libraries: + ind_f.write( + f"{library['name']} \n" + ) + ind_f.write("```\n\n") + + with open(version_tmp_dir / "index.md", "w") as ind_f: + ind_f.write( + """--- +myst: + html_meta: + "http-equiv=refresh": "0; url=getstarted" +--- +""" + ) + ind_f.write("# Index\n\n") + ind_f.write("```") + ind_f.write("\n".join(toc_directives) + "\n") + ind_f.writelines("\n".join(nav_md) + "\n") + ind_f.write("```\n\n") + + +def main(argv=None): + # We will assume that this file is in the same directory as documentation sources and conf.py files. + parser = argparse.ArgumentParser() + parser.add_argument( + "-r", + "--releases", + metavar="GZ_RELEASES", + nargs="*", + help="Names of releases to build. Builds all known releases if empty.", + ) + args, unknown_args = parser.parse_known_args(argv) + + src_dir = Path(__file__).parent + index_yaml = src_dir / "index.yaml" + assert index_yaml.exists() + + with open(index_yaml) as top_index_file: + gz_nav_yaml = yaml.safe_load(top_index_file) + + if not args.releases: + args.releases = [release["name"] for release in gz_nav_yaml["releases"]] + + tmp_dir = src_dir / ".tmp" + for release in args.releases: + generate_sources(gz_nav_yaml, src_dir, tmp_dir, release) + build_dir = src_dir / ".build" / "docs" / release + sphinx_args = [ + "-b", + "dirhtml", + f"{tmp_dir/release}", + f"{build_dir}", + "-D", + f"gz_release={release}", + "-D", + f"gz_root_index_file={index_yaml}", + *unknown_args, + ] + print(f"sphinx_args: {sphinx_args}") + + sphinx_main(sphinx_args) + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/conf.py b/conf.py new file mode 100644 index 000000000..e27c06ee4 --- /dev/null +++ b/conf.py @@ -0,0 +1,141 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2024 Open Source Robotics Foundation +# +# 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. + +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information +import os +from pathlib import Path +import yaml + + +from sphinx.application import Sphinx +from sphinx.config import Config + +project = "Gazebo" +copyright = "2024, Open Robotics" +author = "Gazebo Team" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "myst_parser", + "sphinx_copybutton", + # 'sphinx_sitemap', +] + +templates_path = ["_templates"] + +source_suffix = [ + ".md", +] + +myst_heading_anchors = 4 + +myst_enable_extensions = [ + "amsmath", + "attrs_inline", + "colon_fence", + "deflist", + "dollarmath", + "fieldlist", + "html_admonition", + "html_image", + "linkify", + "replacements", + "smartquotes", + "strikethrough", + "substitution", + "tasklist", +] + +# TODO(azeey) Setting this to true hides a lot of broken links. Consider using +# the `attrs_inline` myst extension and handle external links case by case +# instead of globally. +# myst_all_links_external = True + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "pydata_sphinx_theme" +html_static_path = ["_static"] +html_style = "css/gazebo.css" +html_theme_options = { + "header_links_before_dropdown": 4, + # "use_edit_page_button": True, + "show_toc_level": 1, + "navigation_with_keys": False, + "show_prev_next": False, + "footer_start": [], + "footer_end": [], + "secondary_sidebar_items": ["page-toc", "edit-this-page"], + "navbar_align": "left", + "navbar_center": ["gz-navbar-nav"], + "navbar_end": ["navbar-icon-links", "theme-switcher", "fuel_app_link"], + "pygment_light_style": "sphinx", + "pygment_dark_style": "monokai", + "logo": { + "image_light": "_static/images/logos/gazebo_horz_pos.svg", + "image_dark": "_static/images/logos/gazebo_horz_neg.svg", + }, + "check_switcher": False, +} + +html_sidebars = {"**": ["gz-sidebar-nav"]} +html_baseurl = os.environ.get( + "SPHINX_HTML_BASE_URL", "http://localhost:8000/docs/latest/" +) + + +def load_releases(index_file): + with open(index_file) as top_index_file: + gz_nav_yaml = yaml.safe_load(top_index_file) + + return dict([(release["name"], release) for release in gz_nav_yaml["releases"]]) + + +def config_init(app: Sphinx, config: Config): + if not config.gz_release: + raise RuntimeError("gz_release not provided") + config.release = config.gz_release # type: ignore + config.version = config.gz_release # type: ignore + + # We've disabled "check_switcher" since it doesn't play well with our directory structure. + # So we check for the existence of switcher.json here + # + assert Path(f"{app.srcdir}/_static/switcher.json").exists() + config.html_theme_options["switcher"] = { + "json_url": f"docs/{config.gz_release}/_static/switcher.json", + "version_match": config.gz_release, + } + + try: + releases = load_releases(config.gz_root_index_file) + app.config.html_context["release_info"] = releases[config.gz_release] + except KeyError as e: + print(e) + raise RuntimeError( + f"Provided gz_release '{config.gz_release}' not registered in `index.yaml`" + ) + +def setup(app: Sphinx): + app.add_config_value("gz_release", "", rebuild="env", types=[str]) + app.add_config_value("gz_root_index_file", "", rebuild="env", types=[str]) + app.connect("config-inited", config_init) diff --git a/contributing.md b/contributing.md index b7c3c4d5e..0c5459a25 100644 --- a/contributing.md +++ b/contributing.md @@ -8,29 +8,6 @@ Organization](https://github.com/gazebosim) on GitHub. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. -#### Table of Contents - -[Code of Conduct](https://gazebosim.org/docs/all/contributing#code-of-conduct) - -[Project Design](https://gazebosim.org/docs/all/contributing#project-design) - - * [Repository List](https://gazebosim.org/docs/all/contributing#repository-list) - -[How to Contribute](https://gazebosim.org/docs/all/contributing#how-to-contribute) - - * [Reporting Bugs](https://gazebosim.org/docs/all/contributing#reporting-bugs) - * [Suggesting Enhancements](https://gazebosim.org/docs/all/contributing#suggesting-enhancements) - * [Contributing Code](https://gazebosim.org/docs/all/contributing#contributing-code) - * [Tracking Progress](https://gazebosim.org/docs/all/contributing#tracking-progress) - -[Writing Tests](https://gazebosim.org/docs/all/contributing#writing-tests) - - * [Test Coverage](https://gazebosim.org/docs/all/contributing#test-coverage) - -[Styleguides](https://gazebosim.org/docs/all/contributing#style-guides) - -[Appendix](https://gazebosim.org/docs/all/contributing#appendix) - ## Code of Conduct This project and everyone participating in it is governed by the [Gazebo diff --git a/dome/install_osx_src.md b/dome/install_osx_src.md index ceaa16d48..163d3dc34 100644 --- a/dome/install_osx_src.md +++ b/dome/install_osx_src.md @@ -122,7 +122,7 @@ If you want to compile Ignition Libraries in MacOS Catalina (10.15) you will nee Create a file called `intern.patch` with the following content: -```patch +```diff --- intern.h 2019-12-16 18:17:08.000000000 +0100 +++ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Ruby.framework/Headers/ruby/ruby/intern.h @@ -14,6 +14,10 @@ diff --git a/dome/sensors.md b/dome/sensors.md index 31ab5597e..159cdf555 100644 --- a/dome/sensors.md +++ b/dome/sensors.md @@ -362,14 +362,14 @@ Inside the main we subscribe to the `lidar` topic, and wait until the node is sh Download the [CMakeLists.txt](https://github.com/ignitionrobotics/docs/blob/master/dome/tutorials/sensors/CMakeLists.txt), and in the same folder of `lidar_node` create `build/` directory: -```{.sh} +```sh mkdir build cd build ``` Run cmake and build the code: -```{.sh} +```sh cmake .. make lidar_node ``` diff --git a/dome/web_visualization.md b/dome/web_visualization.md index 97239a74e..4cd1a1c01 100644 --- a/dome/web_visualization.md +++ b/dome/web_visualization.md @@ -62,7 +62,7 @@ matching key using an "auth" call on the websocket. If the ` **NOTE** > As Gazebo GUI is not yet working, running `gz sim` will not work. You can run only the server with -> ```cmd +> ```bat > gz sim -s -v > ``` @@ -152,7 +152,7 @@ page to start using Gazebo! > If your username contains spaces (which is quite common on Windows), you will probably get errors > saying `Invalid partition name [Computer:My User With Spaces]`. Fix this by changing `GZ_PARTITION` > to something else: -> ```cmd +> ```bat > set GZ_PARTITION=test > ``` > Remember to set the same partition in all other consoles. diff --git a/harmonic/sensors.md b/harmonic/sensors.md index 24f3ea514..e95829827 100644 --- a/harmonic/sensors.md +++ b/harmonic/sensors.md @@ -382,14 +382,14 @@ Inside the main we subscribe to the `lidar` topic, and wait until the node is sh Download the [CMakeLists.txt](https://github.com/gazebosim/docs/blob/master/harmonic/tutorials/sensors/CMakeLists.txt), and in the same folder of `lidar_node` create `build/` directory: -```{.sh} +```sh mkdir build cd build ``` Run cmake and build the code: -```{.sh} +```sh cmake .. make lidar_node ``` @@ -398,13 +398,13 @@ make lidar_node Run the node from terminal 1: -```{.sh} +```sh ./build/lidar_node ``` Run the world from terminal 2: -```{.sh} +```sh gz sim sensor_tutorial.sdf ``` @@ -433,7 +433,7 @@ The first command is `gz sim sensor_tutorial.sdf` which launches the world. And the second command is `./build/lidar_node` which runs the `lidar_node`. Save the file as `sensor_launch.gzlaunch`, and then run it using the following command: -```{.sh} +```sh gz launch sensor_launch.gzlaunch ``` diff --git a/release.md b/release.md index 9286e877f..9d66bcd3e 100644 --- a/release.md +++ b/release.md @@ -233,4 +233,10 @@ During the Gazebo Garden development period, this packaage was to use stable and nightly binaries. It is customary to use nightly binaries for all unreleased package versions. +```{toctree} +:hidden: +:maxdepth: 1 +:titlesonly: +releasing/versioning_pre_nightly +``` diff --git a/release_instructions.md b/release_instructions.md index d157fd074..927d75624 100644 --- a/release_instructions.md +++ b/release_instructions.md @@ -64,7 +64,7 @@ features), patch number (patches and bugfixes). **Bumping major number** of the version implies some work to have the [metadata](#metadata-for-releasing) updated correctly. There is a [dedicated -document](releasing/bump_major) that you should go through before continuing to work through the steps in this +document](releasing/bump_major.md) that you should go through before continuing to work through the steps in this document. 1. To update the upstream version a local checkout of the Gz library is diff --git a/releasing/bump_major.md b/releasing/bump_major.md index fea81aad1..8b3750747 100644 --- a/releasing/bump_major.md +++ b/releasing/bump_major.md @@ -1,3 +1,6 @@ +--- +orphan: true +--- # Bump major versions > WARNING: this document is no more than a list of steps. Check with the infra-team diff --git a/releasing/release_repositories.md b/releasing/release_repositories.md index bddbdf3d1..52b7157bc 100644 --- a/releasing/release_repositories.md +++ b/releasing/release_repositories.md @@ -1,3 +1,6 @@ +--- +orphan: true +--- # Release repositories > TODO: the document needs to be completed with real information. The points diff --git a/releasing/versioning_pre_nightly.md b/releasing/versioning_pre_nightly.md index 80e7b36fc..ed9040989 100644 --- a/releasing/versioning_pre_nightly.md +++ b/releasing/versioning_pre_nightly.md @@ -1,4 +1,4 @@ -## Debian/Ubuntu versioning in nightly and prerelease binaries +# Debian/Ubuntu versioning in nightly and prerelease binaries Binary packages produced for prerelease and nightly builds have some particularities to establish the priority among them nicely. @@ -17,7 +17,7 @@ this precedence, the nighlty version uses the trick of setting the version to `{X-1.99.99}` (i.e: if the version to release is `9.0.0`, the nightlies used before the version will use `8.99.99`). -### Version schemes +## Version schemes **Prerelease** versioning scheme: `{upcoming_version}~pre{prerelease_version}` @@ -39,7 +39,7 @@ the version will use `8.99.99`). * `nightly_revision`: revision number to apply to the nightly. It is also used to generate a new nightly using the same date timestamp. -### Versions when mixing stable, prerelease and nightly +## Versions when mixing stable, prerelease and nightly Which version has priority when using prerelease and stable repositories? diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..7c8aebfbf --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +myst-parser[linkify] +pydata-sphinx-theme +pyyaml +sphinx +sphinx-copybutton diff --git a/ros_installation.md b/ros_installation.md index e5bc4b358..26d514803 100644 --- a/ros_installation.md +++ b/ros_installation.md @@ -100,9 +100,9 @@ versions that have the same major number (`gz-sim7_7.0.0`, `gz-sim7_7.1.0`, `gz-sim7_7.0.1`, ...) are binary compatible and thus interchangeable with a given ROS distro. -## Installing Gazebo +### Installing Gazebo -### Gazebo Packages for Ubuntu +#### Gazebo Packages for Ubuntu The easiest way of installing Gazebo on Ubuntu is to use binary packages. There are two main repositories that host Gazebo simulator and Gazebo libraries: one @@ -256,7 +256,7 @@ Getting the latest versions of the Gazebo libraries and simulator is as easy as installing the [`osrfoundation.org` repository](https://gazebosim.org/docs/latest/install_ubuntu_src#install-dependencies) together with the ROS repository. Updates should be fully compatible. -## FAQ +### FAQ #### I am not using ROS at all, which version should I use? diff --git a/tutorials.yaml b/tutorials.yaml deleted file mode 100644 index 72ec21e96..000000000 --- a/tutorials.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# This file is an index of the pages to display on the documentation website -# (https://gazebosim.org/tutorials). The order of the pages in this file -# is reflected on the website's left sidebar. - -releases: - - citadel - - blueprint - - acropolis From 9ab84fc5eaf737bd906711b9de7a9ea3c58cc90d Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Tue, 21 May 2024 00:42:55 -0500 Subject: [PATCH 09/51] Enable 'edit this page' Signed-off-by: Addisu Z. Taddese --- build_multiversion.py | 4 ++-- conf.py | 52 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/build_multiversion.py b/build_multiversion.py index 387520cfb..bc3eb1518 100644 --- a/build_multiversion.py +++ b/build_multiversion.py @@ -101,11 +101,11 @@ def generate_sources(gz_nav_yaml, root_src_dir, tmp_dir, gz_release): def handle_file_url_rename(file_path, file_url): computed_url, ext = os.path.splitext(file_path) - print("renames:", file_path, file_url) + # print("renames:", file_path, file_url) if file_url != computed_url: new_path = file_url + ext # If the file url is inside a directory, we want the new path to end up in the same directory - print("Moving", version_tmp_dir / file_path, version_tmp_dir / new_path) + # print("Moving", version_tmp_dir / file_path, version_tmp_dir / new_path) shutil.move(version_tmp_dir / file_path, version_tmp_dir / new_path) return new_path return file_path diff --git a/conf.py b/conf.py index e27c06ee4..374249b5a 100644 --- a/conf.py +++ b/conf.py @@ -79,7 +79,7 @@ html_style = "css/gazebo.css" html_theme_options = { "header_links_before_dropdown": 4, - # "use_edit_page_button": True, + "use_edit_page_button": True, "show_toc_level": 1, "navigation_with_keys": False, "show_prev_next": False, @@ -89,7 +89,7 @@ "navbar_align": "left", "navbar_center": ["gz-navbar-nav"], "navbar_end": ["navbar-icon-links", "theme-switcher", "fuel_app_link"], - "pygment_light_style": "sphinx", + "pygment_light_style": "tango", "pygment_dark_style": "monokai", "logo": { "image_light": "_static/images/logos/gazebo_horz_pos.svg", @@ -104,6 +104,26 @@ ) +html_context = { + "github_user": "gazebosim", + "github_repo": "docs", + "github_version": "master", + "edit_page_url_template": "{{ github_url }}/{{ github_user }}/{{ github_repo }}" + "/edit/{{ github_version }}/{{ get_file_from_map(file_name) }}", + "edit_page_provider_name": "GitHub", +} + + +def setup_file_map(app: Sphinx, pagename: str, templatename: str, context, doctree): + def get_file_from_map(file_name: str): + result = context["file_name_map"].get(Path(file_name).stem) + if result: + return result + return file_name + + context["get_file_from_map"] = get_file_from_map + + def load_releases(index_file): with open(index_file) as top_index_file: gz_nav_yaml = yaml.safe_load(top_index_file) @@ -111,12 +131,39 @@ def load_releases(index_file): return dict([(release["name"], release) for release in gz_nav_yaml["releases"]]) +def create_file_rename_map(nav_yaml_pages, release): + file_name_map = {} + + prefix = f"{release}/" if release is not None else "" + + for page in nav_yaml_pages: + file_name_map[page["name"]] = f"{prefix}{page['file']}" + + children = page.get("children") + if children: + file_name_map.update(create_file_rename_map(children, release)) + + return file_name_map + + def config_init(app: Sphinx, config: Config): if not config.gz_release: raise RuntimeError("gz_release not provided") config.release = config.gz_release # type: ignore config.version = config.gz_release # type: ignore + file_name_map = {} + + with open(app.config.gz_root_index_file) as f: + file_name_map.update(create_file_rename_map(yaml.safe_load(f)["pages"], None)) + + with open(Path(app.srcdir) / "index.yaml") as f: + file_name_map.update( + create_file_rename_map(yaml.safe_load(f)["pages"], config.release) + ) + + config.html_context["file_name_map"] = file_name_map + # We've disabled "check_switcher" since it doesn't play well with our directory structure. # So we check for the existence of switcher.json here # @@ -138,4 +185,5 @@ def config_init(app: Sphinx, config: Config): def setup(app: Sphinx): app.add_config_value("gz_release", "", rebuild="env", types=[str]) app.add_config_value("gz_root_index_file", "", rebuild="env", types=[str]) + app.connect("html-page-context", setup_file_map) app.connect("config-inited", config_init) From 99fd22c948f44b8cd541d326e24fe32fb9f991f7 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Tue, 21 May 2024 17:13:10 -0500 Subject: [PATCH 10/51] Suppress warnings for external links Signed-off-by: Addisu Z. Taddese --- conf.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/conf.py b/conf.py index 374249b5a..4844fbf92 100644 --- a/conf.py +++ b/conf.py @@ -66,10 +66,11 @@ "tasklist", ] -# TODO(azeey) Setting this to true hides a lot of broken links. Consider using -# the `attrs_inline` myst extension and handle external links case by case -# instead of globally. -# myst_all_links_external = True +nitpicky = False +nitpick_ignore_regex = [ + ("myst", r'/api/.*'), + ("myst", r'/libs/?.*'), # Ignore /libs for now. +] # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output From 28c3b54e58fc430ec3ba802b373558358666633d Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Mon, 3 Jun 2024 10:06:16 -0500 Subject: [PATCH 11/51] Update warning style Signed-off-by: Addisu Z. Taddese --- _static/css/gazebo.css | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/_static/css/gazebo.css b/_static/css/gazebo.css index 6bcf607c8..379f6e5c9 100644 --- a/_static/css/gazebo.css +++ b/_static/css/gazebo.css @@ -108,3 +108,11 @@ button.btn.version-switcher__button { .navbar-brand img { height: 84px; } + +.warning { + border-left: 3px solid rgb(228, 167, 2); + padding: 15px; + margin: 15px 0; + color: #8a6c40; + background: rgb(252, 248, 228); +} From dc032076c81b73fe569141f2baaaab85bb146f7b Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Mon, 3 Jun 2024 12:21:31 -0500 Subject: [PATCH 12/51] Handle dev and old versions, fix going to the correct page after version selection Signed-off-by: Addisu Z. Taddese --- _templates/sections/header.html | 20 +++++++++++++++++ build_multiversion.py | 5 ++++- conf.py | 10 ++++++++- index.yaml | 39 +++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/_templates/sections/header.html b/_templates/sections/header.html index faf2497f6..f6680add1 100644 --- a/_templates/sections/header.html +++ b/_templates/sections/header.html @@ -1,3 +1,23 @@ +{% if not release_info.preferred %} + +{% endif %} + {% include "!sections/header.html" %}
diff --git a/build_multiversion.py b/build_multiversion.py index bc3eb1518..dcfb26bcf 100644 --- a/build_multiversion.py +++ b/build_multiversion.py @@ -86,12 +86,15 @@ def generate_sources(gz_nav_yaml, root_src_dir, tmp_dir, gz_release): name += " (EOL)" elif release["lts"]: name += " (LTS)" + elif release.get("dev", False): + name += " (dev)" switcher.append( { "name": name, "version": release["name"], - "url": f"/docs/{release['name']}", + "url": f"/docs/{release['name']}/", + "preferred": release.get("preferred", False) } ) diff --git a/conf.py b/conf.py index 4844fbf92..078cf16cc 100644 --- a/conf.py +++ b/conf.py @@ -77,7 +77,8 @@ html_theme = "pydata_sphinx_theme" html_static_path = ["_static"] -html_style = "css/gazebo.css" +html_css_files = ["css/gazebo.css"] + html_theme_options = { "header_links_before_dropdown": 4, "use_edit_page_button": True, @@ -97,6 +98,7 @@ "image_dark": "_static/images/logos/gazebo_horz_neg.svg", }, "check_switcher": False, + "show_version_warning_banner": False, # We have our own version, so we disable the one from the theme. } html_sidebars = {"**": ["gz-sidebar-nav"]} @@ -131,6 +133,11 @@ def load_releases(index_file): return dict([(release["name"], release) for release in gz_nav_yaml["releases"]]) +def get_preferred_release(releases: dict): + preferred = [rel for rel in releases.values() if rel.get("preferred", False)] + assert len(preferred) == 1 + print(preferred) + return preferred[0] def create_file_rename_map(nav_yaml_pages, release): file_name_map = {} @@ -177,6 +184,7 @@ def config_init(app: Sphinx, config: Config): try: releases = load_releases(config.gz_root_index_file) app.config.html_context["release_info"] = releases[config.gz_release] + app.config.html_context["preferred_release"] = get_preferred_release(releases) except KeyError as e: print(e) raise RuntimeError( diff --git a/index.yaml b/index.yaml index 84a0d1d4c..995930c83 100644 --- a/index.yaml +++ b/index.yaml @@ -93,9 +93,48 @@ pages: title: What is Fair Use file: fuel/fair_use.md releases: + - name: ionic + lts: false + eol: false + dev: true + description: Supported Sep, 2024 to Sep, 2026 + libraries: + - name: cmake + version: 4 + - name: common + version: 6 + - name: fuel_tools + version: 10 + - name: gui + version: 9 + - name: launch + version: 8 + - name: math + version: 8 + - name: msgs + version: 11 + - name: physics + version: 8 + - name: plugin + version: 3 + - name: rendering + version: 9 + - name: sensors + version: 9 + - name: sim + version: 9 + - name: tools + version: 2 + - name: transport + version: 14 + - name: utils + version: 3 + - name: sdformat + version: 15 - name: harmonic lts: true eol: false + preferred: true # Only one preferred=true is allowed description: Supported Sep, 2023 to Sep, 2028 libraries: - name: cmake From 650a3e444e55561d581238f16547c13cec013398 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Mon, 3 Jun 2024 14:04:45 -0500 Subject: [PATCH 13/51] Use different background for eol vs supported versions Signed-off-by: Addisu Z. Taddese --- _static/css/gazebo.css | 3 +++ _templates/sections/header.html | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/_static/css/gazebo.css b/_static/css/gazebo.css index 379f6e5c9..697cb41b1 100644 --- a/_static/css/gazebo.css +++ b/_static/css/gazebo.css @@ -104,6 +104,9 @@ button.btn.version-switcher__button { color: var(--gz-color-doc-header-text); border-color: var(--gz-color-doc-header-text); } +.bd-header-version-info { + background-color: var(--pst-color-info-bg); +} .navbar-brand img { height: 84px; diff --git a/_templates/sections/header.html b/_templates/sections/header.html index f6680add1..e57894174 100644 --- a/_templates/sections/header.html +++ b/_templates/sections/header.html @@ -1,5 +1,5 @@ {% if not release_info.preferred %} -
+{% else %} +{# Assume /libs #} +
+ +
{% endif %} From 99eb7789286e6d093baf3deb25947aa5450c02fc Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Tue, 4 Jun 2024 15:34:28 -0500 Subject: [PATCH 22/51] Add redirect from /docs Signed-off-by: Addisu Z. Taddese --- build_multiversion.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/build_multiversion.py b/build_multiversion.py index fba9dc18a..c021b462e 100644 --- a/build_multiversion.py +++ b/build_multiversion.py @@ -366,9 +366,10 @@ def main(argv=None): if args.libs: build_libs(gz_nav_yaml, src_dir, tmp_dir, build_dir) else: + build_docs_dir = build_dir / "docs" for release in args.releases: generate_sources(gz_nav_yaml, src_dir, tmp_dir, release) - release_build_dir = build_dir / "docs" / release + release_build_dir = build_docs_dir / release sphinx_args = [ "-b", "dirhtml", @@ -385,7 +386,7 @@ def main(argv=None): if preferred_release["name"] in args.releases: release = preferred_release["name"] for pointer in ["latest", "all"]: - release_build_dir = build_dir / "docs" / pointer + release_build_dir = build_docs_dir / pointer pointer_tmp_dir = tmp_dir/pointer try: pointer_tmp_dir.symlink_to(tmp_dir/release) @@ -409,6 +410,17 @@ def main(argv=None): ] sphinx_main(sphinx_args) + # Create a redirect to "/latest" + redirect_page = build_docs_dir / "index.html" + redirect_page.write_text("""\ + + + + + + +""") + if __name__ == "__main__": sys.exit(main(sys.argv[1:])) From d5f30243af57bd835ba6757ded55585297a9f566 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Tue, 4 Jun 2024 16:00:34 -0500 Subject: [PATCH 23/51] Share conf.py file between docs and libs Signed-off-by: Addisu Z. Taddese --- base_conf.py | 100 ++++++++++++++++++++++++++++++++++++++++++ build_multiversion.py | 4 ++ conf.py | 79 +++------------------------------ libs_conf.py | 73 ++++-------------------------- 4 files changed, 117 insertions(+), 139 deletions(-) create mode 100644 base_conf.py diff --git a/base_conf.py b/base_conf.py new file mode 100644 index 000000000..bb8b5614c --- /dev/null +++ b/base_conf.py @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2024 Open Source Robotics Foundation +# +# 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. + +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = "Gazebo" +copyright = "2024, Open Robotics" +author = "Gazebo Team" + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + "myst_parser", + "sphinx_copybutton", + "sphinx_design", + # 'sphinx_sitemap', +] + +templates_path = ["_templates"] + +source_suffix = [ + ".md", +] + +myst_heading_anchors = 4 + +myst_enable_extensions = [ + "amsmath", + "attrs_inline", + "attrs_block", + "colon_fence", + "deflist", + "dollarmath", + "fieldlist", + "html_admonition", + "html_image", + "linkify", + "replacements", + "smartquotes", + "strikethrough", + "substitution", + "tasklist", +] + +nitpicky = False +nitpick_ignore_regex = [ + ("myst", r'/api/.*'), + ("myst", r'/libs/?.*') +] + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = "pydata_sphinx_theme" +html_static_path = ["_static"] +html_css_files = ["css/gazebo.css"] + +html_theme_options = { + "header_links_before_dropdown": 4, + "use_edit_page_button": True, + "show_toc_level": 1, + "navigation_with_keys": False, + "show_prev_next": False, + "footer_start": [], + "footer_end": [], + "secondary_sidebar_items": ["page-toc", "edit-this-page"], + "navbar_align": "left", + "navbar_center": ["gz-navbar-nav"], + "navbar_end": ["navbar-icon-links", "theme-switcher", "fuel_app_link"], + "pygment_light_style": "tango", + "pygment_dark_style": "monokai", + "logo": { + "image_light": "_static/images/logos/gazebo_horz_pos.svg", + "image_dark": "_static/images/logos/gazebo_horz_neg.svg", + }, + "check_switcher": False, + # We have our own version, so we disable the one from the theme. + "show_version_warning_banner": False, +} + +html_sidebars = {"**": ["gz-sidebar-nav"]} diff --git a/build_multiversion.py b/build_multiversion.py index c021b462e..be5b35d03 100644 --- a/build_multiversion.py +++ b/build_multiversion.py @@ -73,6 +73,7 @@ def generate_sources(gz_nav_yaml, root_src_dir, tmp_dir, gz_release): for dir in ["_static", "_templates"]: shutil.copytree(root_src_dir / dir, version_tmp_dir / dir, dirs_exist_ok=True) + shutil.copy2(root_src_dir / "base_conf.py", version_tmp_dir) shutil.copy2(root_src_dir / "conf.py", version_tmp_dir) for dir in additional_shared_directories: @@ -315,6 +316,7 @@ def generate_libs(gz_nav_yaml, libs_dir): def build_libs(gz_nav_yaml, src_dir, tmp_dir, build_dir): libs_dir = tmp_dir / "libs" libs_dir.mkdir(exist_ok=True) + shutil.copy2(src_dir / "base_conf.py", libs_dir/"base_conf.py") shutil.copy2(src_dir / "libs_conf.py", libs_dir/"conf.py") if len(gz_nav_yaml["releases"]) == 0: print("No releases found in 'index.yaml'.") @@ -362,7 +364,9 @@ def main(argv=None): preferred_release = get_preferred_release(gz_nav_yaml["releases"]) tmp_dir = src_dir / ".tmp" + tmp_dir.mkdir(exist_ok=True) build_dir = src_dir / ".build" + build_dir.mkdir(exist_ok=True) if args.libs: build_libs(gz_nav_yaml, src_dir, tmp_dir, build_dir) else: diff --git a/conf.py b/conf.py index cbf6ec9ea..6c93c48e4 100644 --- a/conf.py +++ b/conf.py @@ -21,6 +21,7 @@ # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information import os +import sys from pathlib import Path import yaml @@ -28,85 +29,14 @@ from sphinx.application import Sphinx from sphinx.config import Config -project = "Gazebo" -copyright = "2024, Open Robotics" -author = "Gazebo Team" - -# -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration - -extensions = [ - "myst_parser", - "sphinx_copybutton", - # 'sphinx_sitemap', -] - -templates_path = ["_templates"] - -source_suffix = [ - ".md", -] - -myst_heading_anchors = 4 - -myst_enable_extensions = [ - "amsmath", - "attrs_inline", - "colon_fence", - "deflist", - "dollarmath", - "fieldlist", - "html_admonition", - "html_image", - "linkify", - "replacements", - "smartquotes", - "strikethrough", - "substitution", - "tasklist", -] - -nitpicky = False -nitpick_ignore_regex = [ - ("myst", r'/api/.*'), - ("myst", r'/libs/?.*'), # Ignore /libs for now. -] - -# -- Options for HTML output ------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output - -html_theme = "pydata_sphinx_theme" -html_static_path = ["_static"] -html_css_files = ["css/gazebo.css"] - -html_theme_options = { - "header_links_before_dropdown": 4, - "use_edit_page_button": True, - "show_toc_level": 1, - "navigation_with_keys": False, - "show_prev_next": False, - "footer_start": [], - "footer_end": [], - "secondary_sidebar_items": ["page-toc", "edit-this-page"], - "navbar_align": "left", - "navbar_center": ["gz-navbar-nav"], - "navbar_end": ["navbar-icon-links", "theme-switcher", "fuel_app_link"], - "pygment_light_style": "tango", - "pygment_dark_style": "monokai", - "logo": { - "image_light": "_static/images/logos/gazebo_horz_pos.svg", - "image_dark": "_static/images/logos/gazebo_horz_neg.svg", - }, - "check_switcher": False, - "show_version_warning_banner": False, # We have our own version, so we disable the one from the theme. -} -html_sidebars = {"**": ["gz-sidebar-nav"]} +sys.path.append(str(Path(__file__).parent)) +from base_conf import * # noqa + html_baseurl = os.environ.get( "SPHINX_HTML_BASE_URL", "http://localhost:8000/docs/latest/" ) - html_context = { "github_user": "gazebosim", "github_repo": "docs", @@ -193,6 +123,7 @@ def config_init(app: Sphinx, config: Config): f"Provided gz_release '{config.gz_release}' not registered in `index.yaml`" ) + def setup(app: Sphinx): app.add_config_value("gz_release", "", rebuild="env", types=[str]) app.add_config_value("gz_root_index_file", "", rebuild="env", types=[str]) diff --git a/libs_conf.py b/libs_conf.py index 5b9844f17..c5a36654a 100644 --- a/libs_conf.py +++ b/libs_conf.py @@ -21,74 +21,17 @@ # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information import os +import sys +from pathlib import Path -project = "Gazebo" -copyright = "2024, Open Robotics" -author = "Gazebo Team" +sys.path.append(str(Path(__file__).parent)) -# -- General configuration --------------------------------------------------- -# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration +# Import the base_conf.py and override settings for /libs +from base_conf import * # noqa -extensions = [ - "myst_parser", - "sphinx_copybutton", - "sphinx_design", -] - -templates_path = ["_templates"] - -source_suffix = [ - ".md", -] - -myst_heading_anchors = 4 - -myst_enable_extensions = [ - "amsmath", - "attrs_inline", - "attrs_block", - "colon_fence", - "deflist", - "dollarmath", - "fieldlist", - "html_admonition", - "html_image", - "linkify", - "replacements", - "smartquotes", - "strikethrough", - "substitution", - "tasklist", -] - -html_theme = "pydata_sphinx_theme" -html_static_path = ["_static"] -html_css_files = ["css/gazebo.css"] - -html_theme_options = { - "header_links_before_dropdown": 4, - "show_toc_level": 1, - "navigation_with_keys": False, - "show_prev_next": False, - "footer_start": [], - "footer_end": [], - "secondary_sidebar_items": [], - "navbar_align": "left", - "navbar_center": ["gz-navbar-nav"], - "navbar_end": ["navbar-icon-links", "theme-switcher", "fuel_app_link"], - "pygment_light_style": "tango", - "pygment_dark_style": "monokai", - "logo": { - "image_light": "_static/images/logos/gazebo_horz_pos.svg", - "image_dark": "_static/images/logos/gazebo_horz_neg.svg", - }, - "check_switcher": False, -} - -html_sidebars = { - "index": [], - "**": ["gz-sidebar-nav"] -} html_baseurl = os.environ.get( "SPHINX_HTML_BASE_URL", "http://localhost:8000/libs/" ) + +html_theme_options["use_edit_page_button"] = False +html_theme_options["secondary_sidebar_items"] = [] From f0e8e85ebddc7b742d03a9e8cdc04f03472ea4bb Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Tue, 4 Jun 2024 16:24:01 -0500 Subject: [PATCH 24/51] Add option for building pointers Signed-off-by: Addisu Z. Taddese --- build_multiversion.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/build_multiversion.py b/build_multiversion.py index be5b35d03..86c97c4f2 100644 --- a/build_multiversion.py +++ b/build_multiversion.py @@ -350,6 +350,12 @@ def main(argv=None): help="Names of releases to build. Builds all known releases if empty.", ) parser.add_argument("--libs", action="store_true", default=False, help="Build /libs page") + parser.add_argument( + "--pointers", + action="store_true", + default=False, + help="Build 'latest' and 'all'", + ) args, unknown_args = parser.parse_known_args(argv) src_dir = Path(__file__).parent @@ -386,9 +392,10 @@ def main(argv=None): *unknown_args, ] sphinx_main(sphinx_args) + # Handle "latest" and "all" - if preferred_release["name"] in args.releases: - release = preferred_release["name"] + release = preferred_release["name"] + if args.pointers and (release in args.releases): for pointer in ["latest", "all"]: release_build_dir = build_docs_dir / pointer pointer_tmp_dir = tmp_dir/pointer From 3807824cb55d179324cf842e3cdc9af24b8054d8 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Wed, 5 Jun 2024 10:38:15 -0500 Subject: [PATCH 25/51] Customize footer Signed-off-by: Addisu Z. Taddese --- _templates/gz-footer.html | 4 ++++ base_conf.py | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 _templates/gz-footer.html diff --git a/_templates/gz-footer.html b/_templates/gz-footer.html new file mode 100644 index 000000000..1af95b789 --- /dev/null +++ b/_templates/gz-footer.html @@ -0,0 +1,4 @@ +

Brought to you by Open Robotics.

+

Except where otherwise noted, the gazebosim.org web pages are licensed under Creative Commons + Attribution 3.0.

diff --git a/base_conf.py b/base_conf.py index bb8b5614c..c7da02cd5 100644 --- a/base_conf.py +++ b/base_conf.py @@ -80,8 +80,9 @@ "show_toc_level": 1, "navigation_with_keys": False, "show_prev_next": False, - "footer_start": [], - "footer_end": [], + "footer_center": ["gz-footer"], + "footer_start": ["sphinx-version"], + # "footer_end": [], "secondary_sidebar_items": ["page-toc", "edit-this-page"], "navbar_align": "left", "navbar_center": ["gz-navbar-nav"], From b8ca4cbbfd224754a3eb67a5c894d54ee891a692 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Wed, 5 Jun 2024 16:08:41 -0500 Subject: [PATCH 26/51] Add more menu items, tweak style Signed-off-by: Addisu Z. Taddese --- _static/css/gazebo.css | 1 + _templates/gz-navbar-nav.html | 14 ++++++++++++-- _templates/sections/header.html | 10 ++++------ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/_static/css/gazebo.css b/_static/css/gazebo.css index d8f4d4918..b7bbfb066 100644 --- a/_static/css/gazebo.css +++ b/_static/css/gazebo.css @@ -1,6 +1,7 @@ html { --pst-font-family-base: Roboto, var(--pst-font-family-base-system); --pst-font-size-base: 14px; + --pst-header-height: 64px; } html[data-theme="light"] { diff --git a/_templates/gz-navbar-nav.html b/_templates/gz-navbar-nav.html index 0e7519dcd..21127a28b 100644 --- a/_templates/gz-navbar-nav.html +++ b/_templates/gz-navbar-nav.html @@ -1,9 +1,19 @@ diff --git a/_templates/sections/header.html b/_templates/sections/header.html index a70eaa5ec..f187e2fbc 100644 --- a/_templates/sections/header.html +++ b/_templates/sections/header.html @@ -42,12 +42,10 @@ {% else %} {# Assume /libs #}
-
diff --git a/base_conf.py b/base_conf.py index 25a2495a8..162827147 100644 --- a/base_conf.py +++ b/base_conf.py @@ -75,6 +75,7 @@ html_theme = "pydata_sphinx_theme" html_static_path = ["_static"] html_css_files = ["css/gazebo.css"] +html_favicon = "_static/icon/favicon.ico" html_theme_options = { "header_links_before_dropdown": 4, @@ -88,8 +89,8 @@ "navbar_align": "left", "navbar_center": ["gz-navbar-nav"], "navbar_end": ["navbar-icon-links", "theme-switcher", "fuel_app_link"], - "pygment_light_style": "tango", - "pygment_dark_style": "monokai", + "pygments_light_style": "tango", + "pygments_dark_style": "monokai", "logo": { "image_light": "_static/images/logos/gazebo_horz_pos.svg", "image_dark": "_static/images/logos/gazebo_horz_neg.svg", diff --git a/build_multiversion.py b/build_multiversion.py index 6aaee7f28..3662bc108 100644 --- a/build_multiversion.py +++ b/build_multiversion.py @@ -14,7 +14,6 @@ # limitations under the License. from pathlib import Path -from sphinx.cmd.build import main as sphinx_main from string import Template import argparse import copy @@ -23,6 +22,7 @@ import requests import shutil import sys +import subprocess import yaml additional_shared_directories = ["images", "releasing"] @@ -331,12 +331,13 @@ def build_libs(gz_nav_yaml, src_dir, tmp_dir, build_dir): generate_libs(gz_nav_yaml, libs_dir) sphinx_args = [ + "sphinx-build", "-b", "dirhtml", f"{libs_dir}", f"{build_dir}", ] - sphinx_main(sphinx_args) + subprocess.run(sphinx_args) def main(argv=None): @@ -395,6 +396,7 @@ def main(argv=None): generate_sources(gz_nav_yaml, src_dir, tmp_dir, release) release_build_dir = build_docs_dir / release sphinx_args = [ + "sphinx-build", "-b", "dirhtml", f"{tmp_dir/release}", @@ -405,7 +407,7 @@ def main(argv=None): f"gz_root_index_file={index_yaml}", *unknown_args, ] - sphinx_main(sphinx_args) + subprocess.run(sphinx_args) # Handle "latest" and "all" release = preferred_release["name"] @@ -423,6 +425,7 @@ def main(argv=None): ) sphinx_args = [ + "sphinx-build", "-b", "dirhtml", f"{pointer_tmp_dir}", @@ -433,7 +436,7 @@ def main(argv=None): f"gz_root_index_file={index_yaml}", *unknown_args, ] - sphinx_main(sphinx_args) + subprocess.run(sphinx_args) # Create a redirect to "/latest" redirect_page = build_docs_dir / "index.html" diff --git a/conf.py b/conf.py index 17295736a..614548934 100644 --- a/conf.py +++ b/conf.py @@ -64,7 +64,6 @@ def load_releases(index_file): def get_preferred_release(releases: dict): preferred = [rel for rel in releases.values() if rel.get("preferred", False)] assert len(preferred) == 1 - print(preferred) return preferred[0] diff --git a/requirements.txt b/requirements.txt index 8ca68902d..78dc33dca 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ myst-parser[linkify] -pydata-sphinx-theme +pydata-sphinx-theme pyyaml sphinx sphinx-copybutton From d4bfbb0be03cc8babe13532c900b3fb8401f1303 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Thu, 6 Jun 2024 02:17:07 -0500 Subject: [PATCH 39/51] Treat all links as external, fix warnings Signed-off-by: Addisu Z. Taddese --- base_conf.py | 7 +------ harmonic/migration_from_ignition.md | 12 ++++++------ 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/base_conf.py b/base_conf.py index 162827147..b29260d9d 100644 --- a/base_conf.py +++ b/base_conf.py @@ -44,6 +44,7 @@ ] myst_heading_anchors = 4 +myst_all_links_external = True myst_enable_extensions = [ "amsmath", @@ -63,12 +64,6 @@ "tasklist", ] -nitpicky = False -nitpick_ignore_regex = [ - ("myst", r'/api/.*'), - ("myst", r'/libs/?.*') -] - # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output diff --git a/harmonic/migration_from_ignition.md b/harmonic/migration_from_ignition.md index 30e5da93a..a0192bc77 100644 --- a/harmonic/migration_from_ignition.md +++ b/harmonic/migration_from_ignition.md @@ -239,7 +239,7 @@ In `CMakeLists.txt` files (and their references in your source files!): **Variables and macro/function calls** -```cpp +``` Find: IGN(ITION)?_GAZEBO Replace: GZ_SIM @@ -255,7 +255,7 @@ Replace: gz_ **Includes** -```cpp +``` Find: include\(Ign Replace: include(Gz @@ -341,7 +341,7 @@ The plugin finder is able to find plugins even if their filenames are stripped o In `.sdf` files and source files (e.g. `.cc`): -```cpp +``` Find: (lib)?ign(ition)?-gazebo([^. ]*)\.so Replace: gz-sim\3 @@ -378,7 +378,7 @@ Replace: gz/ In your message definitions -```cpp +``` Find: ign(ition)?\.gazebo Replace: gz.sim @@ -398,7 +398,7 @@ Sweeping checks everywhere (pay special attention to reviewing these!) **Headers** -```cpp +``` Find: #include\s*([<"])ign(ition)?/gazebo Replace: #include \1gz/sim @@ -416,7 +416,7 @@ Replace: #endif // GZ$1_H **Namespaces** -```cpp +``` Find: namespace\s*ignition Replace: namespace gz From 7f4d8e12cbbe826408b79cced8e14519ab5d92d5 Mon Sep 17 00:00:00 2001 From: "Addisu Z. Taddese" Date: Thu, 6 Jun 2024 02:17:18 -0500 Subject: [PATCH 40/51] Fix scroll padding Signed-off-by: Addisu Z. Taddese --- _static/css/gazebo.css | 14 ++++++++------ _templates/sections/header.html | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/_static/css/gazebo.css b/_static/css/gazebo.css index b7bbfb066..aa9cd46bc 100644 --- a/_static/css/gazebo.css +++ b/_static/css/gazebo.css @@ -2,6 +2,8 @@ html { --pst-font-family-base: Roboto, var(--pst-font-family-base-system); --pst-font-size-base: 14px; --pst-header-height: 64px; + --gz-doc-header-height: 120px; + scroll-padding-top: calc(var(--pst-header-height) + var(--gz-doc-header-height) + 1rem); } html[data-theme="light"] { @@ -69,11 +71,11 @@ pre { display: none; } -.doc-heading { +.doc-header { width: 100%; background-color: var(--gz-color-doc-header); color: var(--gz-color-doc-header-text); - height: 120px; + height: var(--gz-doc-header-height); } .banner { @@ -88,14 +90,14 @@ header.navbar { } .bd-sidebar-primary { - max-height: calc(100vh - var(--pst-header-height) + 120px); - top: calc(var(--pst-header-height) + 120px); + max-height: calc(100vh - var(--pst-header-height) + var(--gz-doc-header-height)); + top: calc(var(--pst-header-height) + var(--gz-doc-header-height)); background-color: var(--gz-color-primary-sidebar); } .bd-sidebar-secondary { - max-height: calc(100vh - var(--pst-header-height) + 120px); - top: calc(var(--pst-header-height) + 120px); + max-height: calc(100vh - var(--pst-header-height) + var(--gz-doc-header-height)); + top: calc(var(--pst-header-height) + var(--gz-doc-header-height)); } .gz-version-switcher { diff --git a/_templates/sections/header.html b/_templates/sections/header.html index 4c1651cef..d046f3e16 100644 --- a/_templates/sections/header.html +++ b/_templates/sections/header.html @@ -23,7 +23,7 @@ {% include "!sections/header.html" %} {% if release_info %} -
+