diff --git a/.github/workflows/ci-format.yml b/.github/workflows/ci-format.yml index bd3c2b8bd79..1f0683c978a 100644 --- a/.github/workflows/ci-format.yml +++ b/.github/workflows/ci-format.yml @@ -24,7 +24,7 @@ jobs: reviewer-stats path: ~/reviews - name: Copy stats - run: ./make_help_scripts/add_pr_stats + run: ./make_help_scripts/add_pr_stats.py - uses: pre-commit/action@v3.0.1 with: extra_args: --all-files --hook-stage manual diff --git a/.github/workflows/sphinx-check-page.yml b/.github/workflows/sphinx-check-page-multiversion.yml similarity index 68% rename from .github/workflows/sphinx-check-page.yml rename to .github/workflows/sphinx-check-page-multiversion.yml index 335712735fe..55619752d2c 100644 --- a/.github/workflows/sphinx-check-page.yml +++ b/.github/workflows/sphinx-check-page-multiversion.yml @@ -1,7 +1,22 @@ -name: "Build Multiversion Page (PR)" +name: "Build Multiversion Page" on: workflow_dispatch: + inputs: + BASE_BRANCH: + description: 'Chose branch to run on' + required: true + default: 'master' + type: choice + options: + - humble + - iron + - master pull_request: + branches: + - master + paths: + - 'make_help_scripts/**' + - 'conf.py' jobs: build-multiversion: @@ -29,6 +44,9 @@ jobs: - name: Install doxygen and graphviz run: sudo apt-get install -y doxygen graphviz - name: Build multiversion with API + env: + BASE_BRANCH: ${{ github.event.inputs.BASE_BRANCH }} + BASE_BRANCH_PR: ${{ github.event.pull_request.head.ref }} run: | git config --local user.email "action@github.com" git config --local user.name "GitHub Action" diff --git a/.gitignore b/.gitignore index c993f6a1fdb..b3d9ff6943a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,16 @@ # ignore pages build by sphinx _build/* +# ignore python cache +**/__pycache__/ + # ignore other docs that are included either by checkout or symlink doc/ros2_control doc/ros2_control_demos doc/ros2_controllers doc/gazebo_ros2_control doc/gz_ros2_control +doc/control_msgs/ +doc/control_toolbox/ +doc/kinematics_interface/ +doc/realtime_tools/ diff --git a/Makefile b/Makefile index de0ce3c74c2..2b01e42bcb4 100644 --- a/Makefile +++ b/Makefile @@ -30,80 +30,80 @@ html-with-api: Makefile @echo Step 1: Creating html files $(SPHINXBUILD) $(SPHINXOPTS) $(SOURCEDIR) $(BUILDDIR)/html @echo Step 2: Building API - ./make_help_scripts/create_api + ./make_help_scripts/create_api.py html-all-subrepos: Makefile @echo Single html file without API @echo Step 1: Cloning all subrepositories - ./make_help_scripts/add_sub_repos + ./make_help_scripts/add_sub_repos.py @echo Step 2: Building documentation $(SPHINXBUILD) $(SPHINXOPTS) $(SOURCEDIR) $(BUILDDIR)/html @echo Step 3: Deleting subrepositories in doc/ folder - ./make_help_scripts/delete_sub_repos + ./make_help_scripts/delete_sub_repos.py html-all-subrepos-with-errors: Makefile @echo Single html file without API @echo Step 1: Cloning all subrepositories - ./make_help_scripts/add_sub_repos + ./make_help_scripts/add_sub_repos.py @echo Step 2: Building documentation $(SPHINXBUILD) $(SPHINXOPTS) -W --keep-going $(SOURCEDIR) $(BUILDDIR)/html @echo Step 3: Deleting subrepositories in doc/ folder - ./make_help_scripts/delete_sub_repos + ./make_help_scripts/delete_sub_repos.py html-all-subrepos-with-api: Makefile @echo Single html file with API @echo Step 1: Cloning all subrepositories - ./make_help_scripts/add_sub_repos + ./make_help_scripts/add_sub_repos.py @echo Step 2: Building documentation $(SPHINXBUILD) $(SPHINXOPTS) $(SOURCEDIR) $(BUILDDIR)/html - @echo Step 3: Deleting subrepositories in doc/ folder - ./make_help_scripts/delete_sub_repos - @echo Step 4: Building API - ./make_help_scripts/create_api + @echo Step 3: Building API + ./make_help_scripts/create_api.py + @echo Step 4: Deleting subrepositories in doc/ folder + ./make_help_scripts/delete_sub_repos.py linkcheck-all-subrepos-with-api: Makefile @echo Single version html file with API and linkcheck @echo Step 1: Cloning all subrepositories - ./make_help_scripts/add_sub_repos + ./make_help_scripts/add_sub_repos.py @echo Step 2: Building API - ./make_help_scripts/create_api - @echo Step 3: Cloning all subrepositories again - ./make_help_scripts/add_sub_repos - @echo Step 4: Check links - ./make_help_scripts/check_links $(BUILDDIR) + ./make_help_scripts/create_api.py + @echo Step 3: Check links + ./make_help_scripts/check_links.py $(BUILDDIR)/html + @echo Step 4: Deleting subrepositories in doc/ folder + ./make_help_scripts/delete_sub_repos.py multiversion: Makefile @echo Building multi version documentation without API @echo Step 1: Creating temporary commits - ./make_help_scripts/add_tmp_commits + ./make_help_scripts/add_tmp_commits.py @echo Step 2: Build multi version documentation sphinx-multiversion $(SPHINXOPTS) $(SOURCEDIR) $(BUILDDIR)/html @echo Step 3: Deleting temporary commits - ./make_help_scripts/delete_tmp_commits + ./make_help_scripts/delete_tmp_commits.py @echo Step 4: Create correct index @echo "
" > "$(BUILDDIR)"/html/index.html multiversion-with-errors: Makefile @echo Building multi version documentation without API @echo Step 1: Creating temporary commits - ./make_help_scripts/add_tmp_commits + ./make_help_scripts/add_tmp_commits.py @echo Step 2: Build multi version documentation sphinx-multiversion $(SPHINXOPTS) -W --keep-going $(SOURCEDIR) $(BUILDDIR)/html @echo Step 3: Deleting temporary commits - ./make_help_scripts/delete_tmp_commits + ./make_help_scripts/delete_tmp_commits.py @echo Step 4: Create correct index @echo "" > "$(BUILDDIR)"/html/index.html multiversion-with-api: Makefile @echo Building multi version documentation with API @echo Step 1: Creating temporary commits - ./make_help_scripts/add_tmp_commits + ./make_help_scripts/add_tmp_commits.py @echo Step 2: Build multi version documentation sphinx-multiversion $(SPHINXOPTS) $(SOURCEDIR) $(BUILDDIR)/html @echo Step 3: Deleting temporary commits - ./make_help_scripts/delete_tmp_commits + ./make_help_scripts/delete_tmp_commits.py @echo Step 4: Building multiverison API - ./make_help_scripts/create_api_multi_version + ./make_help_scripts/create_api_multi_version.py @echo Step 5: Create correct index @echo "" > "$(BUILDDIR)"/html/index.html diff --git a/conf.py b/conf.py index b1aa554fef7..0292d0a3069 100644 --- a/conf.py +++ b/conf.py @@ -67,10 +67,14 @@ # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. -# exclude index.rst files for metapackages for rosdoc2 +# exclude index.rst files from packages/metapackages for rosdoc2 exclude_patterns = ["_build", "Thumbs.db", ".DS_Store", "**/CHANGELOG.rst", "**/README.rst", "doc/ros2_control/ros2_control/**.rst", + "doc/realtime_tools/doc/**.rst", + "doc/control_msgs/doc/**.rst", + "doc/control_toolbox/doc/**.rst", + "doc/kinematics_interface/**.rst", "doc/ros2_controllers/ros2_controllers/**.rst"] # The name of the Pygments (syntax highlighting) style to use. @@ -187,9 +191,17 @@ # Drop any source link suffix html_sourcelink_suffix = "" +# branch from which is started to checkout other branches +# TODO(anyone) use make_help_scripts/deploy_defines.py to set this variable +if os.environ.get('BASE_BRANCH_PR') is not None: + base_branch = os.environ.get('BASE_BRANCH_PR') +elif os.environ.get('BASE_BRANCH') is not None: + base_branch = os.environ.get('BASE_BRANCH') +else: + base_branch = "master" # Add branches you want to whitelist here. -smv_branch_whitelist = r"^(foxy|galactic|humble|iron|master)$" +smv_branch_whitelist = r"^(foxy|galactic|humble|iron|"+ base_branch + r")$" smv_released_pattern = r"^refs/(heads|remotes/[^/]+)/(foxy|galactic|humble|iron).*$" smv_remote_whitelist = r"^(origin)$" smv_latest_version = "iron" @@ -317,7 +329,7 @@ def smv_rewrite_configs(app, config): if app.config.smv_current_version != "": # this map is used to match branches of control.ros.org to ROS distros, e.g., DISTRO macro branch_distro = { - "master": "rolling", + base_branch: "rolling", "iron": "iron", "humble": "humble", "foxy": "foxy", @@ -325,7 +337,7 @@ def smv_rewrite_configs(app, config): } # this map is used to match branches of control.ros.org to REPOS_FILE_BRANCH macro subrepo_branch = { - "master": "master", + base_branch: "master", "iron": "iron", "humble": "humble", "foxy": "foxy", diff --git a/doc/api_list/api_list.rst b/doc/api_list/api_list.rst index 97c59582927..70cc40a6bd6 100644 --- a/doc/api_list/api_list.rst +++ b/doc/api_list/api_list.rst @@ -3,8 +3,12 @@ API Documentation ================= +ros2_control stack +############################# API documentation for the whole framework is parsed by doxygen and can be found `here <../api/index.html>`_. +Per-Package API Documentation +############################# In the following, you can find links to the per-package API documentation published on docs.ros.org. ros2_control diff --git a/doc/api_list/mainpage.md b/doc/api_list/mainpage.md index a914de89a10..7e8a4c4f1a0 100644 --- a/doc/api_list/mainpage.md +++ b/doc/api_list/mainpage.md @@ -2,7 +2,7 @@ This is the API documentation of the ros2_control framework including the follow * [ros2_control][ros2_control] - the main interfaces and components of the framework; * [ros2_controllers][ros2_controllers] - widely used controllers, such as forward command controller, joint trajectory controller, differential drive controller; -* [ros2_control_demos][ros2_control_demos] - examples implementations of common use-cases for a smooth start; +* [ros2_control_demos][ros2_control_demos] - example implementations of common use-cases for a smooth start; * [control_toolbox][control_toolbox] - some widely-used control theory implementations (e.g. PID) used by controllers; * [realtime_tools][realtime_tools] - general toolkit for realtime support, e.g., realtime buffers and publishers; * [control_msgs][control_msgs] - common messages. diff --git a/index.rst b/index.rst index 3b221f5a559..36598f8ba4e 100644 --- a/index.rst +++ b/index.rst @@ -35,13 +35,13 @@ The ros2_control framework consists of the following Github repositories: * `ros2_controllers`_ - widely used controllers, such as forward command controller, joint trajectory controller, differential drive controller; * `control_toolbox`_ - some widely-used control theory implementations (e.g. PID) used by controllers; * `realtime_tools`_ - general toolkit for realtime support, e.g., realtime buffers and publishers; -* `control_msgs`_ - common messages. -* `kinematics_interface`_ - for using C++ kinematics frameworks. +* `control_msgs`_ - common messages; +* `kinematics_interface`_ - for using C++ kinematics frameworks; Additionally, there are following (unreleased) packages are relevant for getting-started and project management: -* `ros2_control_demos`_ - examples implementations of common use-cases for a smooth start; +* `ros2_control_demos`_ - example implementations of common use-cases for a smooth start; * `roadmap`_ - planning and design docs for the project. Development Organisation and Communication diff --git a/make_help_scripts/add_pr_stats b/make_help_scripts/add_pr_stats deleted file mode 100755 index 4dbe1442763..00000000000 --- a/make_help_scripts/add_pr_stats +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash - -# shellckeck source=deploy_defines -# source deploy_defines regardless of startingpoint -DIR="${BASH_SOURCE%/*}" -if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi -. "$DIR/deploy_defines" || { echo "Could not source deploy_defines script. This is needed for correct execution. Exiting!"; exit; } - -add_pr_stats_file diff --git a/make_help_scripts/add_pr_stats.py b/make_help_scripts/add_pr_stats.py new file mode 100755 index 00000000000..0ed5854966c --- /dev/null +++ b/make_help_scripts/add_pr_stats.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 ros2_control maintainers +# +# 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 deploy_defines import add_pr_stats_file + +add_pr_stats_file() diff --git a/make_help_scripts/add_sub_repos b/make_help_scripts/add_sub_repos deleted file mode 100755 index 643b5f0136c..00000000000 --- a/make_help_scripts/add_sub_repos +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env bash - -# shellckeck source=deploy_defines -# source deploy_defines regardless of startingpoint -DIR="${BASH_SOURCE%/*}" -if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi -. "$DIR/deploy_defines" || { echo "Could not source deploy_defines script. This is needed for correct execution. Exiting!"; exit; } - -add_sub_repositories () { - # checkout a base for defined starting point - cd "$base_dir" || { echo "Could not checkout base dir of control.ros.org. Exiting!"; exit "$ERRCODE"; } - for repo_name in "${!subrepo_url[@]}"; do - if [ ! -d "doc/$repo_name" ]; then - echo "Create doc/$repo_name and checkout $base_branch branch" - git clone "${subrepo_url[$repo_name]}" -b "$base_branch" doc/"$repo_name" - else - echo "Update doc/$repo_name and checkout $base_branch branch" - cd doc/"$repo_name" - git fetch origin - git checkout "$base_branch" - git pull - cd "$base_dir" - fi - if [ ! -z ${subrepo_pr[$repo_name]} ]; then - echo "checkout PR: ${subrepo_pr[$repo_name]}" - cd doc/"$repo_name" - git fetch origin ${subrepo_pr[$repo_name]}:PR - git checkout PR - cd "$base_dir" - fi - done -} - -add_sub_repositories -add_pr_stats_file diff --git a/make_help_scripts/add_sub_repos.py b/make_help_scripts/add_sub_repos.py new file mode 100755 index 00000000000..c091ac739b6 --- /dev/null +++ b/make_help_scripts/add_sub_repos.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 ros2_control maintainers +# +# 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. + +import os +import subprocess +import deploy_defines + +def add_sub_repositories(base_branch): + # checkout a base for defined starting point + print(f"base_branch: {base_branch}") + print(f"base_version: {deploy_defines.branch_version[base_branch]}") + os.chdir(deploy_defines.base_dir) + for repo_name, repo_details in deploy_defines.repos.items(): + repo_path = os.path.join("doc", repo_name) + branch = repo_details["branch_version"][deploy_defines.branch_version[base_branch]] + if not os.path.isdir(repo_path): + print(f"Create {repo_path} and checkout {branch} branch") + subprocess.run(["git", "clone", "-b", branch, repo_details["url"], repo_path], check=True) + else: + print(f"Update {repo_path} and checkout {branch} branch") + os.chdir(repo_path) + subprocess.run(["git", "fetch", "origin"], check=True) + subprocess.run(["git", "checkout", branch], check=True) + subprocess.run(["git", "pull"], check=True) + os.chdir(deploy_defines.base_dir) + if repo_details["pr"]: + PR = repo_details["pr"] + print(f"checkout PR: {PR}") + os.chdir(repo_path) + subprocess.run(["git", "fetch", "origin", f"{PR}:PR"], check=True) + subprocess.run(["git", "checkout", "PR"], check=True) + os.chdir(deploy_defines.base_dir) + +if __name__ == "__main__": + add_sub_repositories(deploy_defines.base_branch) + deploy_defines.add_pr_stats_file() diff --git a/make_help_scripts/add_tmp_commits b/make_help_scripts/add_tmp_commits deleted file mode 100755 index d785f0c6c81..00000000000 --- a/make_help_scripts/add_tmp_commits +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env bash - -# shellckeck source=deploy_defines -# source deploy_defines regardless of startingpoint -DIR="${BASH_SOURCE%/*}" -if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi -. "$DIR/deploy_defines" || { echo "Could not source deploy_defines script. This is needed for correct execution. Exiting!"; exit; } - -check_repositories () { - # checkout a base for defined starting point - cd "$base_dir" || { echo "Could not go to base dir of control.ros.org. Exiting!"; exit "$ERRCODE"; } - if [ -n "$(git status --porcelain)" ]; then - echo "control.ros.org repository has uncommitted changes, which will be deleted!"; exit 2; - fi - # check if subrepos do not exist and are no symlinks - for repo_name in "${!subrepo_url[@]}"; do - if [ -L doc/"$repo_name" ]; then - echo "$repo_name is a symlink, delete link or repository will be broken!"; exit 2; - fi - if [ -d doc/"$repo_name" ]; then - echo "$repo_name repository exists already, save your changes because it will be deleted!"; exit 2; - fi - done -} - -add_sub_repositories_and_commit () { - # checkout a base for defined starting point - cd "$base_dir" || { echo "Could not go to base dir of control.ros.org. Exiting!"; exit "$ERRCODE"; } - git checkout "$base_branch" || { echo "Exiting!"; exit "$ERRCODE"; } - - # for each branch from multi version, checkout branch, clone sub repositories with docs add as tmp commit and remove - for branch in "${!branch_version[@]}"; - do echo "Switch to branch: $branch. - With version:${branch_version[$branch]}"; - git checkout "$branch" - # change .gitignore, needed to include subrepositories. sed matches doc/ros2_control*, so all subrepositorie are excluded - sed -i "s/doc\/ros2_control/\#doc\/ros2_control/g" .gitignore - sed -i "s/doc\/gz_ros2_control/\#doc\/gz_ros2_control/g" .gitignore - sed -i "s/doc\/gazebo_ros2_control/\#doc\/gazebo_ros2_control/g" .gitignore - # clone all subrepositories and add as tmp commit to branch of multi version - echo "Clone repositories for $branch and checkout ${branch_version[$branch]}" - for repo_name in "${!subrepo_url[@]}"; - do echo "Create doc/$repo_name"; - git clone "${subrepo_url[$repo_name]}" -b "${branch_version[$branch]}" doc/"$repo_name" 1> /dev/null - cd doc/"$repo_name" || { echo "Could not clone $repo_name to doc/ directory. Exiting!"; exit "$ERRCODE"; } - # remove git repo so that doc files of subrepo can be added to tmp commit - rm -rf .git/ - cd ../../ - done - add_pr_stats_file - git add . - # we don't want to use-precommit to check if subrepos are correct - git commit -m "Add temporary changes for multi version" --no-verify 1> /dev/null - git checkout "$base_branch" - # remove left over folders if existing - for repo_name in "${!subrepo_url[@]}"; - do rm -rf doc/"$repo_name"; - done - done -} - -check_repositories -add_sub_repositories_and_commit diff --git a/make_help_scripts/add_tmp_commits.py b/make_help_scripts/add_tmp_commits.py new file mode 100755 index 00000000000..5bb758d3ac1 --- /dev/null +++ b/make_help_scripts/add_tmp_commits.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 ros2_control maintainers +# +# 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. + +import os +import subprocess +import sys +import shutil +import deploy_defines + +def check_repositories(): + os.chdir(deploy_defines.base_dir) + # Check for uncommitted changes in control.ros.org repository + if subprocess.run(["git", "status", "--porcelain"], capture_output=True, text=True).stdout.strip(): + print("control.ros.org repository has uncommitted changes, which will be deleted!") + subprocess.run(["git", "status", "--porcelain"]) + sys.exit(2) + # Check if subrepos exist or are symlinks + for repo_name in deploy_defines.repos.keys(): + repo_path = os.path.join("doc", repo_name) + if os.path.islink(repo_path): + print(f"{repo_name} is a symlink, delete link or repository will be broken!") + sys.exit(2) + if os.path.isdir(repo_path) and subprocess.run(["git", "-C", repo_path, "status", "--porcelain"], capture_output=True, text=True).stdout.strip(): + print(f"{repo_name} repository exists already, save your changes because it will be deleted!") + sys.exit(2) + +def add_sub_repositories_and_commit(): + os.chdir(deploy_defines.base_dir) + # Checkout the base branch + subprocess.run(["git", "checkout", deploy_defines.base_branch], check=True) + # For each branch from multi version, checkout branch, clone sub repositories with docs add as tmp commit and remove + for branch, version in deploy_defines.branch_version.items(): + print("----------------------------------------------------") + print(f"Switch to branch: {branch} with version: {version}") + subprocess.run(["git", "checkout", branch], check=True) + # Modify .gitignore to include subrepositories + subprocess.run(["sed", "-i", "s/doc\/ros2_control/\#doc\/ros2_control/g", ".gitignore"], check=True) + subprocess.run(["sed", "-i", "s/doc\/gz_ros2_control/\#doc\/gz_ros2_control/g", ".gitignore"], check=True) + subprocess.run(["sed", "-i", "s/doc\/gazebo_ros2_control/\#doc\/gazebo_ros2_control/g", ".gitignore"], check=True) + # Clone all subrepositories and add as tmp commit to branch of multi version + print(f"Clone repositories for {branch} and checkout branches for {version}") + for repo_name, repo_details in deploy_defines.repos.items(): + print(f"Create doc/{repo_name}") + # Remove leftover folders if existing + shutil.rmtree(f"doc/{repo_name}", ignore_errors=True) + branch = repo_details["branch_version"][version] + subprocess.run(["git", "clone", "-b", branch, repo_details["url"], f"doc/{repo_name}"], check=True, stdout=subprocess.DEVNULL) + os.chdir(f"doc/{repo_name}") + # Remove git repo so that doc files of subrepo can be added to tmp commit + shutil.rmtree(".git") + os.chdir("../../") + deploy_defines.add_pr_stats_file() + subprocess.run(["git", "add", "."], check=True) + # We don't want to use-precommit to check if subrepos are correct + subprocess.run(["git", "commit", "-m", "Add temporary changes for multi version", "--no-verify"], check=True, stdout=subprocess.DEVNULL) + subprocess.run(["git", "checkout", deploy_defines.base_branch], check=True) + print("---------- end add_sub_repositories_and_commit ----------------") + +if __name__ == "__main__": + check_repositories() + add_sub_repositories_and_commit() diff --git a/make_help_scripts/check_links b/make_help_scripts/check_links deleted file mode 100755 index f95cc40b958..00000000000 --- a/make_help_scripts/check_links +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash -# This script is used to check the links in the ROS documentation. -# due to a bug in the sphinx linkchecker, github anchors are false positives and -# have to be explicitly ignored -# https://github.com/sphinx-doc/sphinx/issues/9016 - -LOGFILE="linkcheck.log" -cleanup () { - rm "$LOGFILE" - rm -rf doc/api/ -} - -cp -r $1/html/doc/api/. doc/api/ -make linkcheck > "$LOGFILE" -if grep broken "$LOGFILE" | grep -v -E 'github.*Anchor'; then - num_broken=$(grep broken "$LOGFILE" | grep -v -E 'github.*Anchor' | wc -l) - echo "Broken links found: $num_broken" - cleanup - exit 1 -fi -cleanup -exit 0 diff --git a/make_help_scripts/check_links.py b/make_help_scripts/check_links.py new file mode 100755 index 00000000000..0182e19ba86 --- /dev/null +++ b/make_help_scripts/check_links.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python3 +# Copyright (c) 2023 ros2_control maintainers +# +# 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. + +# This script is used to check the links in the ROS documentation. +# due to a bug in the sphinx linkchecker, github anchors are false positives and +# have to be explicitly ignored +# https://github.com/sphinx-doc/sphinx/issues/9016 + +import os +import shutil +import subprocess +import sys + +LOGFILE = "linkcheck.log" + +def cleanup(): + os.remove(LOGFILE) + shutil.rmtree("doc/api/", ignore_errors=True) + +def main(): + if len(sys.argv) != 2: + print("Usage: python check_links.py