diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000000..0dc4c3f88e --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,97 @@ +# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json +name: Deploy Website and Docs + +on: + pull_request: + push: + branches: + - master + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + build_website: + runs-on: ubuntu-latest + steps: + # Build website from gazebosim-web-frontend + - name: Checkout + uses: actions/checkout@v4 + with: + repository: gazebo-web/gazebosim-web-frontend + ref: main + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: npm + cache-dependency-path: package-lock.json + - name: Setup Pages + id: pages + uses: actions/configure-pages@v5 + - name: Install Website dependencies + run: npm ci + - name: Build Website + run: npm run build -- --base-href "${{ steps.pages.outputs.base_url }}/" + # Upload the artifact for local preview + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: website + path: dist + + # Build Docs + build_docs: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Pages + id: pages + uses: actions/configure-pages@v5 + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: 'pip' + - name: Install Docs dependencies + run: pip install -r requirements.txt + - name: Build Docs + run: python build_multiversion.py --pointers --libs --output_dir .build + env: + GZ_DEPLOY_URL: "${{ steps.pages.outputs.base_url }}" + + # Upload the artifact for local preview + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: docs + path: .build + + deploy: + runs-on: ubuntu-latest + needs: [build_website, build_docs] + permissions: + contents: write + # Allow only one concurrent deployment between this and the nightly-upload workflow. + concurrency: + group: pages + cancel-in-progress: false + steps: + - uses: actions/download-artifact@v4 + with: + merge-multiple: true + - name: Upload merged + uses: actions/upload-artifact@v4 + with: + name: website-docs-merged + path: ./ + - name: Commit + uses: peaceiris/actions-gh-pages@v4 + # The workflow upto this point is good for generating a preview, + # but only commit to deploy if we are on the master branch (not a pull request). + if: github.ref == 'refs/heads/master' + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./ + keep_files: true diff --git a/.github/workflows/nightly-upload.yml b/.github/workflows/nightly-upload.yml index cd80dfcfa5..0f9e92cdca 100644 --- a/.github/workflows/nightly-upload.yml +++ b/.github/workflows/nightly-upload.yml @@ -58,17 +58,14 @@ jobs: needs: build runs-on: ubuntu-latest permissions: - id-token: write - contents: read + contents: write + # Allow only one concurrent deployment between this and the deploy workflow. + concurrency: + group: pages + cancel-in-progress: false steps: - name: Checkout uses: actions/checkout@v4 - - name: Configure AWS Credentials - id: creds - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-region: us-east-1 - role-to-assume: arn:aws:iam::200670743174:role/github-oidc-deployment-gz-web-app - uses: actions/download-artifact@v4 id: download with: @@ -81,8 +78,10 @@ jobs: with: name: api-docs path: .api-out/* - - name: Run nightly upload - run: aws s3 sync .api-out/ s3://gazebosim.org/api/ - - name: Invalidate Cloudfront distribution - run: | - aws cloudfront create-invalidation --distribution-id ${{ secrets.CLOUDFRONT_DISTRIBUTION_ID }} --paths '/*' --region us-east-1 + - name: Commit + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./.api-out + destination_dir: api + keep_files: true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..7afd5d306b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.build +.tmp +.venv diff --git a/README.md b/README.md index 0761587011..731656c61b 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 <http://localhost:8000> + +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 0000000000..aa9cd46bcd --- /dev/null +++ b/_static/css/gazebo.css @@ -0,0 +1,149 @@ +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"] { + --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-header { + width: 100%; + background-color: var(--gz-color-doc-header); + color: var(--gz-color-doc-header-text); + height: var(--gz-doc-header-height); +} + +.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) + 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) + var(--gz-doc-header-height)); + top: calc(var(--pst-header-height) + var(--gz-doc-header-height)); +} + +.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); +} +.bd-header-version-info { + background-color: var(--pst-color-info-bg); +} + +.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); +} + +/* Style for /libs */ +.gz-libs-lists { + display: inline; + padding: 0; +} + +.gz-libs-lists p { + display: inline; +} + +.gz-libs-lists li, .gz-libs-cards li { + list-style-type: none; + display: inline; + padding-left: 0px; + padding-right: 30px; +} + +.gz-libs-cards ul { + padding-left: 1em; +} + +.gz-libs-cards .sd-card-text { + display: inline; +} diff --git a/_static/icon/favicon.ico b/_static/icon/favicon.ico new file mode 100644 index 0000000000..3979b1cf68 Binary files /dev/null and b/_static/icon/favicon.ico differ diff --git a/_static/images/logos/gazebo_horz_neg.svg b/_static/images/logos/gazebo_horz_neg.svg new file mode 100644 index 0000000000..1b0aaab8d8 --- /dev/null +++ b/_static/images/logos/gazebo_horz_neg.svg @@ -0,0 +1,110 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + width="979.84998" + height="478.5" + id="svg2" + inkscape:version="0.48.4 r9939" + sodipodi:docname="gazebo_horz_neg.svg"> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1664" + inkscape:window-height="920" + id="namedview3462" + showgrid="false" + inkscape:zoom="0.74470588" + inkscape:cx="525.78645" + inkscape:cy="15.753716" + inkscape:window-x="299" + inkscape:window-y="126" + inkscape:window-maximized="0" + inkscape:current-layer="svg2" /> + <defs + id="defs4"> + <clipPath + id="clipPath3020"> + <path + d="m 0,0 5286.97,0 0,1276 L 0,1276 0,0 z" + id="path3022" + inkscape:connector-curvature="0" /> + </clipPath> + </defs> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <path + style="fill:#000000;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" + d="m 163.48736,206.58057 1.00711,67.97986 60.76224,37.26303 0.50356,-34.07386 33.2346,-19.80647 z" + id="path3924" + inkscape:connector-curvature="0" /> + <path + inkscape:connector-curvature="0" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3024" + d="m 222.38486,244.55712 2.02975,1.25975 c 0.72813,0.45075 1.55275,0.67725 2.38037,0.67725 0.82576,0 1.65338,-0.2265 2.38338,-0.68062 l 2.03225,-1.26763 20.60537,12.76275 -27.51212,17.13138 c -1.32725,0.82362 -2.13288,2.27775 -2.1265,3.84512 l 0.0805,28.07713 -49.7045,-30.86425 49.8315,-30.94088 z m -54.03223,-33.55225 45.47998,28.24225 -45.47998,28.23876 0,-56.48101 z m 125.63548,28.15038 c -0.004,-1.63275 -0.8925,-3.14163 -2.32625,-3.93313 -1.43,-0.79437 -3.17875,-0.7465 -4.5675,0.11775 l -26.73337,16.64738 -20.60313,-12.75875 52.209,-32.51563 c 1.325,-0.82425 2.13125,-2.27387 2.13125,-3.83637 -0.004,-1.55763 -0.8125,-3.00838 -2.1375,-3.82813 l -62.79113,-38.88212 c -1.45749,-0.90375 -3.29824,-0.90125 -4.75487,0.001 l -62.79292,38.99413 c -1.3252,0.82024 -2.13233,2.27049 -2.13233,3.8315 0,0.40574 0,72.09862 0,72.50487 0,1.56062 0.80713,3.01025 2.13233,3.8345 l 62.79292,38.98977 c 0.0307,0.019 0.0625,0.0303 0.0929,0.0478 0.0346,0.0186 0.0634,0.0449 0.0991,0.0659 0.0708,0.0376 0.1455,0.0664 0.21962,0.10254 0.0733,0.0376 0.145,0.0737 0.22226,0.10645 0.11712,0.0474 0.23674,0.0889 0.35637,0.125 0.0709,0.0249 0.13925,0.0513 0.2115,0.0688 0.13425,0.041 0.27187,0.0625 0.40863,0.0884 0.0571,0.0117 0.11725,0.0254 0.17574,0.0288 0.19688,0.0303 0.3955,0.0439 0.59238,0.0439 l 0,0 c 0,0 10e-4,0 0.002,0 0.40925,0 0.82188,-0.0576 1.21825,-0.16748 0.004,-0.004 0.006,-0.004 0.006,-0.004 0.15387,-0.041 0.30525,-0.10254 0.45412,-0.16113 0.0449,-0.0186 0.0928,-0.0298 0.13675,-0.0474 0.12601,-0.0552 0.24263,-0.12891 0.36225,-0.19532 0.066,-0.0361 0.13576,-0.0649 0.20076,-0.10253 l 0.002,-0.003 c 0.003,0 0.003,0 0.003,0 l 0.12063,-0.0762 62.66537,-38.91018 c 1.33125,-0.82762 2.13625,-2.28175 2.13375,-3.84912 l -0.11,-36.32813" /> + <path + inkscape:connector-curvature="0" + style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3026" + d="m 231.20561,280.76812 0.0772,25.623 53.784,-33.398 -0.075,-25.71475 -53.78625,33.48975" /> + <path + inkscape:connector-curvature="0" + style="fill:#f58113;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3028" + d="m 172.55336,202.99313 54.23975,33.67974 54.23925,-33.77937 -54.23438,-33.58475 -54.24462,33.68438" /> + <path + inkscape:connector-curvature="0" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3030" + d="m 408.19061,242.22075 c -1.685,21.81875 -20.725,35.00975 -38.77875,35.00975 -21.9175,0 -39.375,-17.75 -39.375,-37.98738 0,-19.039 15.77125,-37.98537 39.27625,-37.98537 19.43875,0 31.835,13.39112 34.71375,20.82862 l -8.52875,0 c -4.165,-7.23975 -13.8875,-14.183 -26.08625,-14.183 -18.545,0 -32.035,15.07663 -32.035,31.44288 0,16.36175 13.49,31.24112 32.335,31.24112 15.56875,0 27.075,-11.50637 29.6525,-21.72362 l -40.96,0 0,-6.643 49.78625,0" /> + <path + inkscape:connector-curvature="0" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3032" + d="m 450.02686,244.60112 28.465,0 -14.08375,-33.72075 -14.38125,33.72075 z m 10.215,-42.05175 8.2325,0 31.53625,73.392 -8.035,0 -10.605,-24.69337 -34.12,0 -10.71125,24.69337 -7.63875,0 31.34125,-73.392" /> + <path + inkscape:connector-curvature="0" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3034" + d="m 524.92811,269.29487 36.1,-60.103 -35.00875,0 0,-6.6425 43.2375,0 0,6.6425 -36.00125,60.103 37.09375,0 0,6.6465 -45.42125,0 0,-6.6465" /> + <path + inkscape:connector-curvature="0" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3036" + d="m 597.93561,202.54937 40.17,0 0,6.6425 -32.8275,0 0,26.38575 31.73625,0 0,6.64313 -31.73625,0 0,27.07412 32.8275,0 0,6.6465 -40.17,0 0,-73.392" /> + <path + inkscape:connector-curvature="0" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3038" + d="m 676.79936,269.29487 10.3125,0 c 6.1525,0 9.92125,-0.29687 13.8825,-1.88225 4.5625,-1.88287 7.73875,-6.94 7.73875,-12.49562 0,-5.65388 -3.76875,-10.51363 -8.625,-12.39938 -3.475,-1.38825 -6.44875,-1.68512 -14.28625,-1.68512 l -9.0225,0 0,28.46237 z m 0,-35.10887 9.21875,0 c 5.75875,0 9.02875,-0.29688 12.60375,-2.08 3.4675,-1.78713 5.94625,-5.94725 5.94625,-10.3165 0,-3.371 -1.195,-5.7495 -3.0725,-8.03463 -2.87375,-3.27 -7.3425,-4.563 -14.87875,-4.563 l -9.8175,0 0,24.99413 z m -7.3425,-31.63663 18.445,0 c 23.10875,0 24.0025,16.5595 24.0025,19.537 0,8.63138 -5.45375,12.69288 -8.025,14.77638 7.32875,2.97362 12.1925,9.62063 12.1925,18.05425 0,7.0425 -3.27125,13.48775 -8.43125,16.9595 -6.25,3.6655 -11.1125,4.1635 -19.73875,4.06487 l -18.445,0 0,-73.392" /> + <path + inkscape:connector-curvature="0" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3040" + d="m 781.48436,270.58737 c 16.95875,0 31.5375,-13.78762 31.5375,-31.24112 0,-17.16075 -14.18,-31.44288 -31.5375,-31.44288 -16.565,0 -31.44625,13.49063 -31.44625,31.73925 0,16.75775 14.38375,30.94475 31.44625,30.94475 z m 0,-69.32962 c 20.625,0 38.87625,16.36475 38.87625,37.98538 0,21.62112 -18.34625,37.98737 -38.87625,37.98737 -20.83,0 -38.7825,-16.96288 -38.7825,-37.58788 0,-23.11187 19.23875,-38.38487 38.7825,-38.38487" /> +</svg> diff --git a/_static/images/logos/gazebo_horz_pos.svg b/_static/images/logos/gazebo_horz_pos.svg new file mode 100644 index 0000000000..c3f296ee8e --- /dev/null +++ b/_static/images/logos/gazebo_horz_pos.svg @@ -0,0 +1,136 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + width="979.84998" + height="478.5" + id="svg2" + inkscape:version="0.48.4 r9939" + sodipodi:docname="gazebo_horz_pos.svg"> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1393" + inkscape:window-height="1081" + id="namedview3542" + showgrid="false" + inkscape:zoom="0.74470588" + inkscape:cx="472.68004" + inkscape:cy="83.902598" + inkscape:window-x="1041" + inkscape:window-y="140" + inkscape:window-maximized="0" + inkscape:current-layer="svg2" /> + <defs + id="defs4"> + <clipPath + id="clipPath3020"> + <path + d="m 0,0 5286.97,0 0,1276 L 0,1276 0,0 z" + id="path3022" + inkscape:connector-curvature="0" /> + </clipPath> + <clipPath + id="clipPath3111"> + <path + d="m 0,0 5286.98,0 0,1276 L 0,1276 0,0 z" + id="path3113" + inkscape:connector-curvature="0" /> + </clipPath> + </defs> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + </cc:Work> + </rdf:RDF> + </metadata> + <path + style="fill:#ffffff;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" + d="m 164.74024,205.99021 1.89902,67.41531 59.81923,38.92997 0.94951,-34.65717 35.13192,-19.46498 z" + id="path4004" + inkscape:connector-curvature="0" /> + <g + transform="translate(-170.935,-653.61217)" + id="layer1"> + <g + transform="matrix(1.25,0,0,-1.25,330.42374,972.61217)" + id="g3103"> + <g + transform="scale(0.1,0.1)" + id="g3105"> + <g + id="g3107"> + <g + clip-path="url(#clipPath3111)" + id="g3109"> + <path + d="m 503.164,595.555 16.238,-10.078 c 5.825,-3.625 12.422,-5.422 19.043,-5.422 6.606,0 13.227,1.797 19.067,5.449 L 573.77,595.621 738.613,493.543 518.516,356.48 c -10.618,-6.589 -17.063,-18.222 -17.012,-30.761 L 502.148,101.102 104.512,348.016 503.164,595.555 z M 70.9062,863.949 434.746,638.031 70.9062,412.125 l 0,451.824 z M 1075.99,638.766 c -0.03,13.066 -7.14,25.117 -18.61,31.464 -11.44,6.336 -25.43,5.977 -36.54,-0.937 L 806.973,536.109 642.148,638.18 1059.82,898.297 c 10.6,6.601 17.05,18.203 17.05,30.691 -0.03,12.461 -6.5,24.067 -17.1,30.637 L 557.441,1270.67 c -11.66,7.23 -26.386,7.21 -38.039,-0.02 L 17.0586,958.719 C 6.45703,952.145 0,940.543 0,928.055 0,924.809 0,351.266 0,348.016 0,335.531 6.45703,323.934 17.0586,317.34 L 519.402,5.42188 c 0.246,-0.15235 0.5,-0.24219 0.743,-0.38282 0.277,-0.14844 0.507,-0.35937 0.793,-0.52734 0.566,-0.30078 1.164,-0.53125 1.757,-0.82031 0.586,-0.30079 1.16,-0.58985 1.778,-0.85157 0.937,-0.3789 1.894,-0.71093 2.851,-1 0.567,-0.19922 1.114,-0.41015 1.692,-0.55078 1.074,-0.328122 2.175,-0.499998 3.269,-0.707029 0.457,-0.09375 0.938,-0.203125 1.406,-0.230469 C 535.266,0.109375 536.855,0 538.43,0 l 0,0 c 0,0 0.008,0 0.015,0 3.274,0 6.575,0.460938 9.746,1.33984 0.032,0.03125 0.051,0.03125 0.051,0.03125 1.231,0.32813 2.442,0.82032 3.633,1.28907 0.359,0.14843 0.742,0.23828 1.094,0.3789 1.008,0.44141 1.941,1.03125 2.898,1.5625 0.528,0.28906 1.086,0.51953 1.606,0.82032 l 0.015,0.02734 c 0.024,0 0.024,0 0.024,0 L 558.477,6.05859 1059.8,317.34 c 10.65,6.621 17.09,18.254 17.07,30.793 l -0.88,290.633" + id="path3115" + style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none" + inkscape:connector-curvature="0" /> + <path + d="m 573.73,305.855 0.618,-204.984 430.272,267.184 -0.6,205.73 -430.29,-267.93" + id="path3117" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + inkscape:connector-curvature="0" /> + <path + d="M 104.512,928.055 538.43,658.629 972.344,928.844 538.469,1197.53 104.512,928.055" + id="path3119" + style="fill:#f58113;fill-opacity:1;fill-rule:nonzero;stroke:none" + inkscape:connector-curvature="0" /> + <path + d="m 1989.61,614.242 c -13.48,-174.551 -165.8,-280.086 -310.23,-280.086 -175.34,0 -315,142.012 -315,303.887 0,152.336 126.17,303.895 314.21,303.895 155.51,0 254.68,-107.118 277.71,-166.622 l -68.23,0 c -33.32,57.911 -111.1,113.457 -208.69,113.457 -148.36,0 -256.28,-120.601 -256.28,-251.531 0,-130.898 107.92,-249.933 258.68,-249.933 124.55,0 216.6,92.05 237.22,173.773 l -327.68,0 0,53.16 398.29,0" + id="path3121" + style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none" + inkscape:connector-curvature="0" /> + <path + d="m 2324.3,595.199 227.72,0 -112.67,269.758 -115.05,-269.758 z m 81.72,336.418 65.86,0 252.29,-587.148 -64.28,0 -84.84,197.558 -272.96,0 -85.69,-197.558 -61.11,0 250.73,587.148" + id="path3123" + style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none" + inkscape:connector-curvature="0" /> + <path + d="m 2923.5,397.633 288.81,480.82 -280.08,0 0,53.164 345.92,0 0,-53.164 -288.03,-480.82 296.76,0 0,-53.164 -363.38,0 0,53.164" + id="path3125" + style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none" + inkscape:connector-curvature="0" /> + <path + d="m 3507.56,931.617 321.37,0 0,-53.164 -262.62,0 0,-211.062 253.89,0 0,-53.149 -253.89,0 0,-216.609 262.62,0 0,-53.164 -321.37,0 0,587.148" + id="path3127" + style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none" + inkscape:connector-curvature="0" /> + <path + d="m 4138.48,397.633 82.5,0 c 49.22,0 79.38,2.375 111.06,15.058 36.5,15.059 61.91,55.536 61.91,99.981 0,45.234 -30.16,84.109 -69,99.18 -27.8,11.125 -51.59,13.496 -114.28,13.496 l -72.19,0 0,-227.715 z m 0,280.887 73.75,0 c 46.08,0 72.23,2.375 100.82,16.64 27.76,14.301 47.58,47.578 47.58,82.512 0,26.98 -9.55,46.016 -24.57,64.297 -23.01,26.164 -58.75,36.484 -119.04,36.484 l -78.54,0 0,-199.933 z m -58.75,253.097 147.58,0 c 184.86,0 192.01,-132.48 192.01,-156.301 0,-69.05 -43.63,-101.558 -64.2,-118.211 58.63,-23.808 97.54,-76.964 97.54,-144.433 0,-56.336 -26.17,-107.902 -67.44,-135.672 -50,-29.336 -88.91,-33.32 -157.91,-32.531 l -147.58,0 0,587.148" + id="path3129" + style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none" + inkscape:connector-curvature="0" /> + <path + d="m 4975.96,387.309 c 135.67,0 252.31,110.304 252.31,249.933 0,137.266 -113.44,251.531 -252.31,251.531 -132.52,0 -251.56,-107.918 -251.56,-253.906 0,-134.078 115.06,-247.558 251.56,-247.558 z m 0,554.629 c 165,0 311.02,-130.918 311.02,-303.895 0,-172.969 -146.78,-303.887 -311.02,-303.887 -166.64,0 -310.25,135.711 -310.25,300.711 0,184.895 153.9,307.071 310.25,307.071" + id="path3131" + style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none" + inkscape:connector-curvature="0" /> + </g> + </g> + </g> + </g> + </g> +</svg> diff --git a/_templates/fuel_app_link.html b/_templates/fuel_app_link.html new file mode 100644 index 0000000000..5e9c34e13e --- /dev/null +++ b/_templates/fuel_app_link.html @@ -0,0 +1 @@ +<a class="btn btn-outline-secondary" href="https://app.gazebosim.org">APP</a> diff --git a/_templates/gz-footer.html b/_templates/gz-footer.html new file mode 100644 index 0000000000..1af95b7893 --- /dev/null +++ b/_templates/gz-footer.html @@ -0,0 +1,4 @@ +<p> Brought to you by <a href="https://openrobotics.org">Open Robotics</a>. </p> +<p> Except where otherwise noted, the gazebosim.org web pages are licensed under <a + href="https://creativecommons.org/licenses/by/3.0/us/">Creative Commons + Attribution 3.0</a>. </p> diff --git a/_templates/gz-navbar-nav.html b/_templates/gz-navbar-nav.html new file mode 100644 index 0000000000..c52a58fbb1 --- /dev/null +++ b/_templates/gz-navbar-nav.html @@ -0,0 +1,19 @@ +<nav class="navbar-nav"> + <ul class="bd-navbar-elements navbar-nav"> + <li class="nav-item"><a class="nav-link nav-internal" href="{{ deploy_url }}/features">Features</a></li> + <li class="nav-item"><a class="nav-link nav-internal" href="{{ deploy_url }}/showcase">Showcase</a></li> + <li class="nav-item"><a class="nav-link nav-internal" href="{{ deploy_url }}/docs">Docs</a></li> + <li class="nav-item"><a class="nav-link nav-internal" href="https://community.gazebosim.org/">Community</a></li> + <li class="nav-item dropdown"> + <button class="btn dropdown-toggle nav-item" type="button" data-bs-toggle="dropdown" aria-expanded="false" aria-controls="pst-nav-more-links">More</button> + <ul class="dropdown-menu"> + <li class="nav-item"><a class="nav-link nav-internal" href="{{ deploy_url }}/about">About</a></li> + <li class="nav-item"><a class="nav-link nav-internal" href='https://community.gazebosim.org' title="Discussion forum">Community</a> + <li class="nav-item"><a class="nav-link nav-internal" href='https://robotics.stackexchange.org' title="Technical help">Answers</a> + <li class="nav-item"><a class="nav-link nav-internal" href="https://blog.openrobotics.org/tag/gazebo">Blog</a> + <li class="nav-item"><a class="nav-link nav-internal" href="{{ deploy_url }}/media">Media</a></li> + </ul> + </li> + </ul> +</nav> + diff --git a/_templates/gz-sidebar-nav.html b/_templates/gz-sidebar-nav.html new file mode 100644 index 0000000000..db9b8f866b --- /dev/null +++ b/_templates/gz-sidebar-nav.html @@ -0,0 +1,16 @@ +{# Temlate to generate sidedbar navigation from level 0 toc items #} +<nav class="bd-docs-nav bd-links" + aria-label="{{ _('Section Navigation') }}"> + <div class="bd-toc-item navbar-nav"> + {{- generate_toctree_html( + "sidebar", + startdepth=0, + show_nav_level=theme_show_nav_level | int, + maxdepth=theme_navigation_depth | int, + collapse=theme_collapse_navigation | tobool, + includehidden=theme_sidebar_includehidden | tobool, + titles_only=True + ) + -}} + </div> +</nav> diff --git a/_templates/gz-version-switcher.html b/_templates/gz-version-switcher.html new file mode 100644 index 0000000000..5808190226 --- /dev/null +++ b/_templates/gz-version-switcher.html @@ -0,0 +1,4 @@ +<div class="gz-version-switcher"> + <span class="fs-4 fw-light pe-2">Release:</span> +{%- include 'version-switcher.html' -%} +</div> diff --git a/_templates/sections/header.html b/_templates/sections/header.html new file mode 100644 index 0000000000..d046f3e16d --- /dev/null +++ b/_templates/sections/header.html @@ -0,0 +1,52 @@ +{% if release_info %} + {% if not release_info.preferred %} + <aside aria-label="Version warning" class="bd-header-announcement bd-header-version-{{'warning' if release_info.eol else 'info'}}" style="min-height: 3rem;"> + <div class="bd-header-announcement__content"> + <div class="sidebar-message"> + {% if release_info.eol %} + This is documentation for <strong>Gazebo {{ release_info.name | capitalize}}</strong>, which has reached its EOL + (end-of-life) and is no longer officially supported. + {% elif release_info.dev %} + This is documentation for <strong> Gazebo {{ release_info.name | capitalize}}</strong> which is still under + development. + {% else %} + This is documentation for <strong> Gazebo {{ release_info.name | capitalize}}</strong>, + an older but still supported version of Gazebo. {% endif %} + <a class="btn text-wrap font-weight-bold ms-3 my-1 align-baseline pst-button-link-to-stable-version" + href="{{ pathto(root_doc) }}../{{preferred_release.name}}/{{pagename}}">Switch to the latest stable version</a> + </div> + </div> + </aside> + {% endif %} +{% endif %} + +{% include "!sections/header.html" %} + +{% if release_info %} +<div class="doc-header"> + <div class="banner d-flex flex-column-reverse flex-sm-row"> + <div> + <div class="d-none d-sm-block"> + <span class="d-inline fs-2">Docs / Gazebo {{ release_info.name | capitalize }}</span> + {% if release_info.lts %} + <span class="badge bg-primary fs-4 fw-light ms-2">LTS</span> + {% elif release_info.eol %} + <span class="badge bg-danger fs-4 fw-light ms-2">EOL</span> + {% endif %} + </div> + <span>{{ release_info.description}}</span> + </div> + {%- include 'gz-version-switcher.html' -%} + </div> +</div> +{% else %} +{# Assume /libs #} +<div class="doc-heading"> + <div class="banner"> + <div class="d-sm-block"> + <div class="h1">Development Libraries</div> + <span>Explore the complete set of development libraries offered by Gazebo.</span> + </div> + </div> +</div> +{% endif %} diff --git a/base_conf.py b/base_conf.py new file mode 100644 index 0000000000..b29260d9db --- /dev/null +++ b/base_conf.py @@ -0,0 +1,102 @@ +# -*- 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 + +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_all_links_external = True + +myst_enable_extensions = [ + "amsmath", + "attrs_inline", + "attrs_block", + "colon_fence", + "deflist", + "dollarmath", + "fieldlist", + "html_admonition", + "html_image", + "linkify", + "replacements", + "smartquotes", + "strikethrough", + "substitution", + "tasklist", +] + +# -- 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_favicon = "_static/icon/favicon.ico" + +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_center": ["gz-footer"], + "footer_start": ["sphinx-version"], + "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"], + "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", + }, + "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"]} + +html_context = { + "deploy_url": os.environ.get("GZ_DEPLOY_URL", "") +} diff --git a/blueprint/ros_integration.md b/blueprint/ros_integration.md index be30d83f92..520865f38f 100644 --- a/blueprint/ros_integration.md +++ b/blueprint/ros_integration.md @@ -101,4 +101,4 @@ The screenshot shows all the shell windows and their expected content (it was taken using ROS Melodic): - + diff --git a/build_multiversion.py b/build_multiversion.py new file mode 100644 index 0000000000..3662bc108c --- /dev/null +++ b/build_multiversion.py @@ -0,0 +1,454 @@ +# -*- 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 string import Template +import argparse +import copy +import json +import os +import requests +import shutil +import sys +import subprocess +import yaml + +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 / "base_conf.py", version_tmp_dir) + 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) + + deploy_url = os.environ.get("GZ_DEPLOY_URL", "") + # 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)" + elif release.get("dev", False): + name += " (dev)" + + switcher.append( + { + "name": name, + "version": release["name"], + "url": f"{deploy_url}/docs/{release['name']}/", + "preferred": release.get("preferred", False) + } + ) + + 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']} <https://gazebosim.org/api/{library['name']}/{library['version']}>\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 get_preferred_release(releases: dict): + preferred = [rel for rel in releases if rel.get("preferred", False)] + assert len(preferred) == 1 + return preferred[0] + + +def github_repo_name(lib_name): + prefix = "gz-" if lib_name != "sdformat" else "" + return f"{prefix}{lib_name.replace('_','-')}" + + +def github_branch(repo_name, version): + return f"{repo_name}{version}" if repo_name != "sdformat" else f"sdf{version}" + + +def github_url(lib_name): + return f"https://github.com/gazebosim/{github_repo_name(lib_name)}" + + +def api_url(lib_name, version): + if lib_name == "sdformat": + return "http://sdformat.org/api" + else: + return f"https://gazebosim.org/api/{lib_name}/{version}" + + +def get_github_content(lib_name, version, file_path): + repo_name = github_repo_name(lib_name) + branch = github_branch(repo_name, version) + url = f"https://raw.githubusercontent.com/gazebosim/{repo_name}/{branch}/{file_path}" + if os.environ.get("SKIP_FETCH_CONTENT", False): + return f"Skipped fetching context from {url}" + + print(f"fetching {url}") + result = requests.get(url, allow_redirects=True) + return result.text + + +def generate_individual_lib(library, libs_dir): + lib_name = library["name"] + version = library["version"] + cur_lib_dir = libs_dir / lib_name + cur_lib_dir.mkdir(exist_ok=True) + + template = Template("""\ +# $name + +{.gz-libs-lists} +- [{material-regular}`code;2em` Source Code]($github_url) +- [{material-regular}`description;2em` API & Tutorials]($api_url) + +::::{tab-set} + +:::{tab-item} Readme +$readme +::: + +:::{tab-item} Changelog +$changelog +::: + +:::: + """) + + mapping = { + "name": lib_name, + "readme": get_github_content(lib_name, version, "README.md"), + "changelog": get_github_content(lib_name, version, "Changelog.md"), + "github_url": github_url(lib_name), + "api_url": api_url(lib_name, version), + } + with open(cur_lib_dir / "index.md", "w") as f: + f.write(template.substitute(mapping)) + + +def generate_libs(gz_nav_yaml, libs_dir): + libraries = get_preferred_release(gz_nav_yaml["releases"])["libraries"] + library_directives = "\n".join([ + f"{library['name'].capitalize()} <{library['name']}/index>" + for library in libraries + ]) + + index_md_header_template = Template("""\ +# Libraries + +```{toctree} +:maxdepth: 1 +:hidden: +:titlesonly: +$library_directives +``` + +""") + + library_card_template = Template("""\ +:::{card} [$name_cap]($name/index) +:class-card: gz-libs-cards + - [{material-regular}`fullscreen;2em` Details]($name/index) + - [{material-regular}`code;2em` Source Code]($github_url) + - [{material-regular}`description;2em` API & Tutorials]($api_url) ++++, + +$description +::: + + +""") + with open(libs_dir / "index.md", "w") as f: + f.write( + index_md_header_template.substitute(library_directives=library_directives) + ) + + for library in sorted(libraries, key=lambda lib: lib["name"]): + name = library["name"] + try: + description = gz_nav_yaml["library_info"][name]["description"] + except KeyError as e: + print( + f"Description for library {name} not found." + "Make sure there is an entry for it in index.yaml" + ) + print(e) + description = "" + mapping = { + "name": name, + "name_cap": name.capitalize(), + "github_url": github_url(name), + "api_url": api_url(name, library["version"]), + "description": description, + } + f.write(library_card_template.substitute(mapping)) + + generate_individual_lib(library, 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'.") + return + + for dir in ["_static", "_templates"]: + shutil.copytree(src_dir / dir, libs_dir / dir, dirs_exist_ok=True) + + build_dir = build_dir / "libs" + + generate_libs(gz_nav_yaml, libs_dir) + + sphinx_args = [ + "sphinx-build", + "-b", + "dirhtml", + f"{libs_dir}", + f"{build_dir}", + ] + subprocess.run(sphinx_args) + + +def main(argv=None): + src_dir = Path(__file__).parent + + # 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.", + ) + parser.add_argument( + "--output_dir", default=src_dir / ".build", help="Path to output directory" + ) + parser.add_argument( + "--libs", action="store_true", default=False, help="Build /libs page" + ) + parser.add_argument( + "--libs_only", action="store_true", default=False, help="Build only /libs page" + ) + parser.add_argument( + "--pointers", + action="store_true", + default=False, + help="Build 'latest' and 'all'", + ) + + args, unknown_args = parser.parse_known_args(argv) + + 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"]] + + preferred_release = get_preferred_release(gz_nav_yaml["releases"]) + tmp_dir = src_dir / ".tmp" + tmp_dir.mkdir(exist_ok=True) + build_dir = Path(args.output_dir) + build_dir.mkdir(exist_ok=True) + if args.libs or args.libs_only: + build_libs(gz_nav_yaml, src_dir, tmp_dir, build_dir) + + if args.libs_only: + return + + 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_docs_dir / release + sphinx_args = [ + "sphinx-build", + "-b", + "dirhtml", + f"{tmp_dir/release}", + f"{release_build_dir }", + "-D", + f"gz_release={release}", + "-D", + f"gz_root_index_file={index_yaml}", + *unknown_args, + ] + subprocess.run(sphinx_args) + + # Handle "latest" and "all" + 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 + try: + pointer_tmp_dir.symlink_to(tmp_dir/release) + except FileExistsError: + # It's okay for it to exist, but make sure it's a symlink + if not pointer_tmp_dir.is_symlink: + raise RuntimeError( + f"{pointer_tmp_dir} already exists and is not a symlink" + ) + + sphinx_args = [ + "sphinx-build", + "-b", + "dirhtml", + f"{pointer_tmp_dir}", + f"{release_build_dir}", + "-D", + f"gz_release={release}", + "-D", + f"gz_root_index_file={index_yaml}", + *unknown_args, + ] + subprocess.run(sphinx_args) + + # Create a redirect to "/latest" + redirect_page = build_docs_dir / "index.html" + redirect_page.write_text("""\ +<!DOCTYPE html> +<html> + <head> + <meta content="0; url=latest" http-equiv="refresh" /> + </head> +</html> +""") + + +if __name__ == "__main__": + sys.exit(main(sys.argv[1:])) diff --git a/citadel/index.yaml b/citadel/index.yaml index f58d5ec5d0..f293b7a473 100644 --- a/citadel/index.yaml +++ b/citadel/index.yaml @@ -41,6 +41,9 @@ pages: - name: troubleshooting title: Troubleshooting file: troubleshooting.md + - name: ign_docker_env + title: Dockerized Dev Env + file: ign_docker_env.md - name: comparison title: Feature Comparison file: comparison.md diff --git a/citadel/install_osx_src.md b/citadel/install_osx_src.md index 77e564cb4a..8c9b78edaa 100644 --- a/citadel/install_osx_src.md +++ b/citadel/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 @@ @@ -140,7 +140,7 @@ Create a file called `intern.patch` with the following content: Now we can apply the patch: -```{.sh} +```sh sudo patch -p0 < intern.patch ``` @@ -164,7 +164,7 @@ Create a file called `config.patch` with the following content: Now we can appply the patch: -```{.sh} +```sh sudo patch -p0 < config.patch ``` diff --git a/citadel/ros_integration.md b/citadel/ros_integration.md index 460a698549..22184cefa4 100644 --- a/citadel/ros_integration.md +++ b/citadel/ros_integration.md @@ -96,4 +96,4 @@ The screenshot shows all the shell windows and their expected content (it was taken using ROS Melodic): - + diff --git a/citadel/sensors.md b/citadel/sensors.md index c5f8f101fe..34d0e120a8 100644 --- a/citadel/sensors.md +++ b/citadel/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/citadel/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 ``` @@ -378,13 +378,13 @@ make lidar_node Run the node from terminal 1: -```{.sh} +```sh ./build/lidar_node ``` Run the world from terminal 2: -```{.sh} +```sh ign gazebo sensor_tutorial.sdf ``` @@ -413,7 +413,7 @@ The first command is `ign gazebo 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.ign`, and then run it using the following command: -```{.sh} +```sh ign launch sensor_launch.ign ``` diff --git a/conf.py b/conf.py new file mode 100644 index 0000000000..6145489349 --- /dev/null +++ b/conf.py @@ -0,0 +1,128 @@ +# -*- 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 sys +from pathlib import Path +import yaml + + +from sphinx.application import Sphinx +from sphinx.config import Config + + +sys.path.append(str(Path(__file__).parent)) +from base_conf import * # noqa + +html_baseurl = f"{html_context['deploy_url']}/docs/latest" # noqa + +html_context.update({ + "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) + + 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 + return preferred[0] + + +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 + # + assert Path(f"{app.srcdir}/_static/switcher.json").exists() + config.html_theme_options["switcher"] = { + "json_url": f"{html_context['deploy_url']}/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] + app.config.html_context["preferred_release"] = get_preferred_release(releases) + + 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("html-page-context", setup_file_map) + app.connect("config-inited", config_init) diff --git a/contributing.md b/contributing.md index b7c3c4d5ec..0c5459a259 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 ceaa16d487..2c4e5ceae0 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 @@ @@ -140,7 +140,7 @@ Create a file called `intern.patch` with the following content: Now we can apply the patch: -```{.sh} +```sh sudo patch -p0 < intern.patch ``` @@ -164,7 +164,7 @@ Create a file called `config.patch` with the following content: Now we can appply the patch: -```{.sh} +```sh sudo patch -p0 < config.patch ``` diff --git a/dome/sensors.md b/dome/sensors.md index 31ab5597ec..6bb641cfd8 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 ``` @@ -378,13 +378,13 @@ make lidar_node Run the node from terminal 1: -```{.sh} +```sh ./build/lidar_node ``` Run the world from terminal 2: -```{.sh} +```sh ign gazebo sensor_tutorial.sdf ``` @@ -413,7 +413,7 @@ The first command is `ign gazebo 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.ign`, and then run it using the following command: -```{.sh} +```sh ign launch sensor_launch.ign ``` diff --git a/dome/web_visualization.md b/dome/web_visualization.md index 97239a74ee..4cd1a1c01f 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 `<admin_authorization 1. Is you notice an issue with web visualization, then please file a ticket at - [https://gitlab.com/ignitionrobotics/web/app/-/issues](https://gitlab.com/ignitionrobotics/web/app/-/issues). + [https://github.com/gazebo-web/gzweb/issues](https://github.com/gazebo-web/gzweb/issues). ## Troubleshooting diff --git a/edifice/install_osx_src.md b/edifice/install_osx_src.md index d476c1054f..5bb5b06add 100644 --- a/edifice/install_osx_src.md +++ b/edifice/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 @@ @@ -140,7 +140,7 @@ Create a file called `intern.patch` with the following content: Now we can apply the patch: -```{.sh} +```sh sudo patch -p0 < intern.patch ``` @@ -164,7 +164,7 @@ Create a file called `config.patch` with the following content: Now we can appply the patch: -```{.sh} +```sh sudo patch -p0 < config.patch ``` diff --git a/edifice/sensors.md b/edifice/sensors.md index ef80024ef0..22b560c77b 100644 --- a/edifice/sensors.md +++ b/edifice/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/edifice/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 ``` @@ -378,13 +378,13 @@ make lidar_node Run the node from terminal 1: -```{.sh} +```sh ./build/lidar_node ``` Run the world from terminal 2: -```{.sh} +```sh ign gazebo sensor_tutorial.sdf ``` @@ -413,7 +413,7 @@ The first command is `ign gazebo 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.ign`, and then run it using the following command: -```{.sh} +```sh ign launch sensor_launch.ign ``` diff --git a/fortress/install_osx_src.md b/fortress/install_osx_src.md index 4eea0450ee..9f3ae62103 100644 --- a/fortress/install_osx_src.md +++ b/fortress/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 @@ @@ -140,7 +140,7 @@ Create a file called `intern.patch` with the following content: Now we can apply the patch: -```{.sh} +```sh sudo patch -p0 < intern.patch ``` @@ -148,7 +148,7 @@ sudo patch -p0 < intern.patch Create a file called `config.patch` with the following content: -```patch +```diff --- config.h 2019-12-16 18:19:13.000000000 +0100 +++ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Ruby.framework/Headers/ruby/ruby/config.h @@ -410,6 +410,6 @@ @@ -164,7 +164,7 @@ Create a file called `config.patch` with the following content: Now we can appply the patch: -```{.sh} +```sh sudo patch -p0 < config.patch ``` diff --git a/fortress/sensors.md b/fortress/sensors.md index bfa6d5ccf4..2ac11c522a 100644 --- a/fortress/sensors.md +++ b/fortress/sensors.md @@ -384,14 +384,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/fortress/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 ``` @@ -400,13 +400,13 @@ make lidar_node Run the node from terminal 1: -```{.sh} +```sh ./build/lidar_node ``` Run the world from terminal 2: -```{.sh} +```sh ign gazebo sensor_tutorial.sdf ``` @@ -435,7 +435,7 @@ The first command is `ign gazebo 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.ign`, and then run it using the following command: -```{.sh} +```sh ign launch sensor_launch.ign ``` diff --git a/garden/install_osx_src.md b/garden/install_osx_src.md index 7038e44fb6..3caba545cc 100644 --- a/garden/install_osx_src.md +++ b/garden/install_osx_src.md @@ -136,7 +136,7 @@ If you want to compile Gazebo Libraries in MacOS Catalina (10.15) you will need 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 @@ @@ -154,7 +154,7 @@ Create a file called `intern.patch` with the following content: Now we can apply the patch: -```{.sh} +```sh sudo patch -p0 < intern.patch ``` @@ -162,7 +162,7 @@ sudo patch -p0 < intern.patch Create a file called `config.patch` with the following content: -```patch +```diff --- config.h 2019-12-16 18:19:13.000000000 +0100 +++ /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Ruby.framework/Headers/ruby/ruby/config.h @@ -410,6 +410,6 @@ @@ -178,7 +178,7 @@ Create a file called `config.patch` with the following content: Now we can appply the patch: -```{.sh} +```sh sudo patch -p0 < config.patch ``` diff --git a/garden/migration_from_ignition.md b/garden/migration_from_ignition.md index 07ad69c901..b0fe2a9f67 100644 --- a/garden/migration_from_ignition.md +++ b/garden/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 @@ -271,7 +271,7 @@ Replace: gz_find_package(Gz- **Project Names** -```cpp +``` Find: ignition-gazebo Replace: gz-sim @@ -288,7 +288,7 @@ Replace: gz- Migrate source macros and environment variables -```cpp +``` Find: IGN(ITION)?_GAZEBO Replace: GZ_SIM @@ -319,7 +319,7 @@ Additionally, the logging macros have also been migrated! Migrate any uses! In `.sdf` files: -```cpp +``` Find: <ignition Replace: <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 @@ -359,7 +359,7 @@ Replace: gz:: In Python files (e.g. `.py`) -```cpp +``` Find: ignition.gazebo Replace: gz.sim @@ -369,7 +369,7 @@ Replace: gz. In Ruby files (e.g. `.i`, `.rb`) -```cpp +``` Find: ign(ition)?/ Replace: gz/ ``` @@ -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 @@ -449,13 +449,13 @@ And also be mindful that certain instances of `gazebo` (usually as part of an AP Where you used to use: -```cpp +``` ign gazebo shapes.sdf ``` Now you should use: -```cpp +``` gz sim shapes.sdf ``` diff --git a/garden/sensors.md b/garden/sensors.md index 079e154233..fbf229c243 100644 --- a/garden/sensors.md +++ b/garden/sensors.md @@ -361,14 +361,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/garden/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 ``` @@ -377,13 +377,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 ``` @@ -412,7 +412,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/get_started.md b/get_started.md index bac67148b0..bfc8d40c6b 100644 --- a/get_started.md +++ b/get_started.md @@ -17,22 +17,22 @@ 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) (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) -| Mac Monterey | [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) +| Ubuntu 22.04 Jammy | [Gazebo Harmonic](/docs/harmonic/install_ubuntu){.external} (recommended), [Gazebo Garden](/docs/garden/install_ubuntu){.external} and [Gazebo Fortress](/docs/fortress/install_ubuntu){.external} (recommended if using ROS 2 Humble or Iron) +| Ubuntu 20.04 Focal | [Gazebo Garden](/docs/garden/install_ubuntu){.external} (recommended), [Gazebo Fortress](/docs/fortress/install_ubuntu){.external} and [Gazebo Citadel](/docs/citadel/install_ubuntu){.external} +| Ubuntu 18.04 Bionic | [Gazebo Citadel](/docs/citadel/install_ubuntu){.external} +| Mac Ventura | [Gazebo Harmonic](/docs/harmonic/install_osx){.external} (recommended), [Gazebo Garden](/docs/garden/install_osx){.external}, [Gazebo Fortress](/docs/fortress/install_osx){.external} and [Gazebo Citadel](/docs/citadel/install_osx){.external} +| Mac Monterey | [Gazebo Harmonic](/docs/harmonic/install_osx){.external} (recommended), [Gazebo Garden](/docs/garden/install_osx){.external}, [Gazebo Fortress](/docs/fortress/install_osx){.external} and [Gazebo Citadel](/docs/citadel/install_osx){.external} | Windows | Support via Conda-Forge is not fully functional, as there are known runtime issues [see this issue for details](https://github.com/gazebosim/gz-sim/issues/168). If the desired platform is not listed above or if a particular feature in a -given [Gazebo release](/docs/latest/releases) is needed, +given [Gazebo release](releases) is needed, there is an installation package per release available with all the installation options: -* [Gazebo Harmonic installation](/docs/harmonic/install) options (EOL 2028 Sep) -* [Gazebo Garden installation](/docs/garden/install) options (EOL 2024 Sep) -* [Gazebo Fortress (LTS) installation](/docs/fortress/install) options (EOL 2026 Sep) -* [Gazebo Citadel (LTS) installation](/docs/citadel/install) options (EOL 2024 Dec) +* [Gazebo Harmonic installation](/docs/harmonic/install){.external} options (EOL 2028 Sep) +* [Gazebo Garden installation](/docs/garden/install){.external} options (EOL 2024 Sep) +* [Gazebo Fortress (LTS) installation](/docs/fortress/install){.external} options (EOL 2026 Sep) +* [Gazebo Citadel (LTS) installation](/docs/citadel/install){.external} options (EOL 2024 Dec) ## Step 2: Run @@ -95,14 +95,14 @@ custom SDF file. ## Step 4: Explore and learn This tutorial has covered the basics of getting started with Gazebo. -Starting with Citadel, there are more [versioned tutorials](/docs/citadel/tutorials) +Starting with Citadel, there are more [versioned tutorials](/docs/citadel/tutorials){.external} covering the basics of the GUI, creating worlds and robots, and more. Each [Gazebo library](/libs) also has a set of tutorials and examples. Explore these resources, and don't forget to ask questions and find solutions at [answers.gazebosim.org](http://answers.gazebosim.org). -# macOS +## macOS On macOS, you will need to run Gazebo using two terminals, one for the server and another for the GUI: diff --git a/harmonic/install_windows_src.md b/harmonic/install_windows_src.md index 59e28efec1..b3e3a3d5ff 100644 --- a/harmonic/install_windows_src.md +++ b/harmonic/install_windows_src.md @@ -144,7 +144,7 @@ page to start using Gazebo! > **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/migration_from_ignition.md b/harmonic/migration_from_ignition.md index 30e5da93ae..d630b85584 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 @@ -271,7 +271,7 @@ Replace: gz_find_package(Gz- **Project Names** -```cpp +``` Find: ignition-gazebo Replace: gz-sim @@ -288,7 +288,7 @@ Replace: gz- Migrate source macros and environment variables -```cpp +``` Find: IGN(ITION)?_GAZEBO Replace: GZ_SIM @@ -319,7 +319,7 @@ Additionally, the logging macros have also been migrated! Migrate any uses! In `.sdf` files: -```cpp +``` Find: <ignition Replace: <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 @@ -359,7 +359,7 @@ Replace: gz:: In Python files (e.g. `.py`) -```cpp +``` Find: ignition.gazebo Replace: gz.sim @@ -369,7 +369,7 @@ Replace: gz. In Ruby files (e.g. `.i`, `.rb`) -```cpp +``` Find: ign(ition)?/ Replace: gz/ ``` @@ -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 @@ -449,13 +449,13 @@ And also be mindful that certain instances of `gazebo` (usually as part of an AP Where you used to use: -```cpp +``` ign gazebo shapes.sdf ``` Now you should use: -```cpp +``` gz sim shapes.sdf ``` diff --git a/harmonic/sensors.md b/harmonic/sensors.md index 24f3ea514b..e958298278 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/index.yaml b/index.yaml index 15dfd4d34e..d77496a73a 100644 --- a/index.yaml +++ b/index.yaml @@ -97,9 +97,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 @@ -385,4 +424,38 @@ releases: version: 6 - name: sdformat version: 8 - +# This dictionary is used to supply the description of each library and any other +# information about each library that doesn't change between releases +library_info: + cmake: + description: Provides modules that are used to find dependencies of Gazebo projects and generate cmake targets for consumers of Gazebo projects to link against. + common: + description: A collection of useful classes and functions for handling many command tasks. This includes parsing 3D mesh files, managing console output, and using PID controllers. + fuel_tools: + description: A C++ client library and command line tools for interacting with Gazebo Fuel servers + gui: + description: A framework for graphical user interfaces centered around QT. Each component in Gazebo GUI is an independent plugin + launch: + description: Launch is a system that runs and manages plugins and programs. A configuration script can be used to specify which programs and plugins to run. Alternatively, individual programs and plugins can be run from the command line. + math: + description: A small, fast, and high performance math library. This library is a self-contained set of classes and functions suitable for robot applications. + msgs: + description: Standard set of message definitions, used by Gazebo Transport, and other applications. + physics: + description: A plugin based interface to physics engines, such as ODE, Bullet, and DART. + plugin: + description: A plugin loading library + rendering: + description: A plugin based interface to rendering engines, such as OGRE and Optix. + sensors: + description: A large set of sensor and noise models suitable for generating realistic data in simulation. + sim: + description: Gazebo simulates multiple robots in a 3D environment, with extensive dynamic interaction between objects. + tools: + description: Gazebo tools provides the gz command line tool that accepts multiple subcommands. + transport: + description: The transport library combines ZeroMQ with Protobufs to create a fast and efficient message passing system. Asynchronous message publication and subscription is provided along with service calls and discovery. + sdformat: + description: Simulation Description Format parser and description files. + utils: + description: General purpose classes and functions with minimal dependencies. It includes command line parsing, a helper class to implement the PIMPL pattern, macros to suppress warnings, etc. diff --git a/ionic/install_windows_src.md b/ionic/install_windows_src.md index 3506a2ab5c..2bf62c2603 100644 --- a/ionic/install_windows_src.md +++ b/ionic/install_windows_src.md @@ -144,7 +144,7 @@ page to start using Gazebo! > **NOTE** > As Gazebo GUI is not yet working, running `gz sim` will not work. You can run only the server with -> ```cmd +> ```batch > 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 +> ```batch > set GZ_PARTITION=test > ``` > Remember to set the same partition in all other consoles. diff --git a/ionic/migration_from_ignition.md b/ionic/migration_from_ignition.md index 6798db1d87..5d0eafa300 100644 --- a/ionic/migration_from_ignition.md +++ b/ionic/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 @@ -271,7 +271,7 @@ Replace: gz_find_package(Gz- **Project Names** -```cpp +``` Find: ignition-gazebo Replace: gz-sim @@ -288,7 +288,7 @@ Replace: gz- Migrate source macros and environment variables -```cpp +``` Find: IGN(ITION)?_GAZEBO Replace: GZ_SIM @@ -319,7 +319,7 @@ Additionally, the logging macros have also been migrated! Migrate any uses! In `.sdf` files: -```cpp +``` Find: <ignition Replace: <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 @@ -359,7 +359,7 @@ Replace: gz:: In Python files (e.g. `.py`) -```cpp +``` Find: ignition.gazebo Replace: gz.sim @@ -369,7 +369,7 @@ Replace: gz. In Ruby files (e.g. `.i`, `.rb`) -```cpp +``` Find: ign(ition)?/ Replace: gz/ ``` @@ -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 @@ -449,13 +449,13 @@ And also be mindful that certain instances of `gazebo` (usually as part of an AP Where you used to use: -```cpp +``` ign gazebo shapes.sdf ``` Now you should use: -```cpp +``` gz sim shapes.sdf ``` diff --git a/ionic/sensors.md b/ionic/sensors.md index c8afc7ed07..0d2d3705bd 100644 --- a/ionic/sensors.md +++ b/ionic/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/ionic/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/libs_conf.py b/libs_conf.py new file mode 100644 index 0000000000..59518ed694 --- /dev/null +++ b/libs_conf.py @@ -0,0 +1,34 @@ +# -*- 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 sys +from pathlib import Path + +sys.path.append(str(Path(__file__).parent)) + +# Import the base_conf.py and override settings for /libs +from base_conf import * # noqa + +html_baseurl = f"{html_context['deploy_url']}/libs" # noqa + +html_theme_options["use_edit_page_button"] = False +html_theme_options["secondary_sidebar_items"] = [] diff --git a/release.md b/release.md index 9286e877f1..9d66bcd3e3 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 d157fd074a..927d756240 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 fea81aad14..8b37507478 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 bddbdf3d1b..52b7157bca 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 80e7b36fcc..ed90409899 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 0000000000..78dc33dcab --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +myst-parser[linkify] +pydata-sphinx-theme +pyyaml +sphinx +sphinx-copybutton +sphinx-design +requests diff --git a/ros_installation.md b/ros_installation.md index 40eb95fb2d..5518ad1780 100644 --- a/ros_installation.md +++ b/ros_installation.md @@ -98,9 +98,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 @@ -254,7 +254,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 72ec21e964..0000000000 --- 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