Skip to content

Commit

Permalink
Merge pull request #35 from ami-iit/update_ci
Browse files Browse the repository at this point in the history
Update supported Python versions and update CI/CD
  • Loading branch information
diegoferigo authored May 17, 2024
2 parents e08ab4a + 44068bc commit 11d2768
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 46 deletions.
35 changes: 18 additions & 17 deletions .github/workflows/ci_cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ jobs:

steps:

- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: "3.*"

Expand All @@ -50,7 +50,7 @@ jobs:
python -c "import packaging.version as v; v.Version(\"$(python -m setuptools_scm)\")"
- name: Upload artifacts
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
path: dist/*
name: dist
Expand All @@ -73,10 +73,9 @@ jobs:
- apt
- conda
python:
- "3.8"
- "3.9"
- "3.10"
- "3.11"
- "3.12"
exclude:
- os: macos-latest
type: apt
Expand All @@ -87,15 +86,14 @@ jobs:

- name: Set up Python
if: matrix.type == 'apt'
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}

- uses: conda-incubator/setup-miniconda@v2
- uses: conda-incubator/setup-miniconda@v3
if: matrix.type == 'conda'
with:
python-version: ${{ matrix.python }}
miniforge-variant: Mambaforge
miniforge-version: latest
channels: conda-forge
channel-priority: true
Expand All @@ -112,27 +110,28 @@ jobs:
- name: Install conda dependencies
if: matrix.type == 'conda'
# Note: pytest-icdiff creates problems on macOS.
run: |
mamba install -y \
conda install -y \
coloredlogs \
mashumaro \
numpy \
packaging \
resolve-robotics-uri-py \
scipy \
trimesh \
xmltodict \
black \
isort \
pptree \
idyntree \
pytest \
robot_descriptions \
trimesh
# pytest-icdiff \ # creates problems on macOS
mamba install -y gz-sim7 idyntree
libgz-tools2 \
libsdformat13
- name: Download Python packages
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
path: dist
name: dist
Expand All @@ -150,13 +149,15 @@ jobs:

- name: Import the package
run: python -c "import rod"
env:
ROD_LOGGING_LEVEL: DEBUG

- uses: actions/checkout@v3
if: matrix.os != 'windows-latest'
- uses: actions/checkout@v4

- name: Run tests
if: matrix.os != 'windows-latest'
run: pytest
env:
ROD_LOGGING_LEVEL: DEBUG

publish:
name: Publish to PyPI
Expand All @@ -166,7 +167,7 @@ jobs:
steps:

- name: Download Python packages
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
path: dist
name: dist
Expand Down
5 changes: 2 additions & 3 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,9 @@ classifiers =
Operating System :: MacOS
Operating System :: Microsoft :: Windows
Programming Language :: Python :: 3
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Programming Language :: Python :: 3.12
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: Implementation :: CPython
Topic :: Games/Entertainment :: Simulation
Expand All @@ -53,7 +52,7 @@ zip_safe = False
packages = find:
package_dir =
=src
python_requires = >=3.8
python_requires = >=3.10
install_requires =
coloredlogs
mashumaro
Expand Down
41 changes: 35 additions & 6 deletions src/rod/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
# ===============================


def _is_editable():
def installation_is_editable():
"""
Check if the rod package is installed in editable mode.
"""
Expand All @@ -51,12 +51,41 @@ def _is_editable():
return rod_package_dir not in site.getsitepackages()


# Initialize the logging verbosity depending on the installation mode.
logging.configure(
level=logging.LoggingLevel.DEBUG if _is_editable() else logging.LoggingLevel.WARNING
)
def get_default_logging_level(env_var: str) -> logging.LoggingLevel:
"""
Get the default logging level.
Args:
env_var: The environment variable to check.
Returns:
The logging level to set.
"""

import os

# Define the default logging level depending on the installation mode.
default_logging_level = (
logging.LoggingLevel.DEBUG
if installation_is_editable()
else logging.LoggingLevel.WARNING
)

# Allow to override the default logging level with an environment variable.
try:
return logging.LoggingLevel[
os.environ.get(env_var, default_logging_level.name).upper()
]
except KeyError as exc:
msg = f"Invalid logging level defined in {env_var}='{os.environ[env_var]}'"
raise RuntimeError(msg) from exc


# Configure the logger with the default logging level.
logging.configure(level=get_default_logging_level(env_var="ROD_LOGGING_LEVEL"))

del _is_editable
del installation_is_editable
del get_default_logging_level

# =====================================
# Check for compatible sdformat version
Expand Down
55 changes: 35 additions & 20 deletions tests/test_meshbuilder.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import os
import pathlib
import tempfile

import numpy as np
Expand All @@ -9,53 +7,70 @@


def test_builder_creation():

# Create a mesh of a box primitive.
mesh = trimesh.creation.box([1, 1, 1])

# Temporary write to file because rod Mesh works with uri
with tempfile.NamedTemporaryFile(suffix=".stl") as fp:
mesh.export(fp.name, file_type="stl")
# Temporary write to file because rod Mesh works with uri.
with tempfile.TemporaryDirectory() as tmp:
with tempfile.NamedTemporaryFile(suffix=".stl", dir=tmp, delete=False) as fp:

mesh.export(fp.name, file_type="stl")
fp.close()

builder = MeshBuilder(
name="test_mesh",
mesh_path=fp.name,
mass=1.0,
scale=np.array([1.0, 1.0, 1.0]),
)

builder = MeshBuilder(
name="test_mesh",
mesh_path=fp.name,
mass=1.0,
scale=np.array([1.0, 1.0, 1.0]),
)
assert (
builder.mesh.vertices.shape == mesh.vertices.shape
), f"{builder.mesh.vertices.shape} != {mesh.vertices.shape}"

assert (
builder.mesh.faces.shape == mesh.faces.shape
), f"{builder.mesh.faces.shape} != {mesh.faces.shape}"

assert (
builder.mesh.moment_inertia.all() == mesh.moment_inertia.all()
), f"{builder.mesh.moment_inertia} != {mesh.moment_inertia}"

assert builder.mesh.volume == mesh.volume, f"{builder.mesh.volume} != {mesh.volume}"


def test_builder_creation_custom_mesh():

# Create a custom mesh
vertices = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]])
faces = np.array([[0, 1, 2], [0, 2, 3]])
mesh = trimesh.Trimesh(vertices=vertices, faces=faces)

# Temporary write to file because rod Mesh works with uri
with tempfile.NamedTemporaryFile(suffix=".stl") as fp:
mesh.export(fp.name, file_type="stl")
# Temporary write to file because rod Mesh works with uri.
with tempfile.TemporaryDirectory() as tmp:
with tempfile.NamedTemporaryFile(suffix=".stl", dir=tmp, delete=False) as fp:

mesh.export(fp.name, file_type="stl")
fp.close()

builder = MeshBuilder(
name="test_mesh",
mesh_path=fp.name,
mass=1.0,
scale=np.array([1.0, 1.0, 1.0]),
)

builder = MeshBuilder(
name="test_mesh",
mesh_path=fp.name,
mass=1.0,
scale=np.array([1.0, 1.0, 1.0]),
)
assert (
builder.mesh.vertices.shape == mesh.vertices.shape
), f"{builder.mesh.vertices.shape} != {mesh.vertices.shape}"

assert (
builder.mesh.faces.shape == mesh.faces.shape
), f"{builder.mesh.faces.shape} != {mesh.faces.shape}"

assert (
builder.mesh.moment_inertia.all() == mesh.moment_inertia.all()
), f"{builder.mesh.moment_inertia} != {mesh.moment_inertia}"

assert builder.mesh.volume == mesh.volume, f"{builder.mesh.volume} != {mesh.volume}"

0 comments on commit 11d2768

Please sign in to comment.