Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion colcon_ros_cargo/task/ament_cargo/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,23 @@ def write_cargo_config_toml(package_paths):
:param package_paths: A mapping of package names to paths
"""
patches = {pkg: {'path': str(path)} for pkg, path in package_paths.items()}
content = {'patch': {'crates-io': patches}}

config_dir = Path.cwd() / '.cargo'
config_dir.mkdir(exist_ok=True)
cargo_config_toml_out = config_dir / 'config.toml'

if cargo_config_toml_out.exists():
with cargo_config_toml_out.open('r') as toml_file:
content = toml.load(toml_file)
Comment on lines +119 to +120

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we wrap this in a try except so the tool doesn't crash if the file being loaded is malformed?

else:
content = {}

if 'patch' not in content:
content['patch'] = {}

# remove old entries
content['patch']['crates-io'] = patches

with cargo_config_toml_out.open('w') as toml_file:
toml.dump(content, toml_file)

Expand Down
112 changes: 112 additions & 0 deletions test/test_cargo_config_toml.py

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Format this file with flake8. CI is failing on this test specifically

def test_flake8():

I think this answers your question in the description as well

I didn't use a code formatter for build.py as I couldn't find any guidelines or config for common tooling.

Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import pytest
from pathlib import Path
import toml
import os

from colcon_ros_cargo.task.ament_cargo.build import write_cargo_config_toml


@pytest.fixture
def temp_workspace(tmp_path):
"""Create a temporary workspace directory."""
original_cwd = os.getcwd()
os.chdir(tmp_path)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixture expects a tmp_path variable, but the usage of it doesn't ever fill this value. I don't think this will run as os.chdir does expect a value

>>> import os
>>> os.chdir(None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: chdir: path should be string, bytes, os.PathLike or integer, not NoneType
>>> os.chdir("")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: ''

yield tmp_path
os.chdir(original_cwd)


def test_write_cargo_config_toml_creates_new_file(temp_workspace):
"""Test that config.toml is created when it doesn't exist."""
package_paths = {
"my_package": Path("/path/to/my_package"),
"other_package": Path("/path/to/other_package"),
}

write_cargo_config_toml(package_paths)

config_file = temp_workspace / ".cargo" / "config.toml"
assert config_file.exists()

with config_file.open("r") as f:
content = toml.load(f)

assert "patch" in content
assert "crates-io" in content["patch"]
assert content["patch"]["crates-io"]["my_package"] == {
"path": "/path/to/my_package"
}
assert content["patch"]["crates-io"]["other_package"] == {
"path": "/path/to/other_package"
}


def test_write_cargo_config_toml_merges_entries(temp_workspace):
"""Test that the it merges its changes and preserves existing config."""
config_dir = temp_workspace / ".cargo"
config_dir.mkdir(exist_ok=True)
config_file = config_dir / "config.toml"

existing_content = {
"build": {
"target": "x86_64-unknown-linux-gnu",
"jobs": 4,
},
"patch": {
"crates-io": {
"existing_package": {"path": "/existing/path"},
}
},
}

with config_file.open("w") as f:
toml.dump(existing_content, f)

package_paths = {
"new_package": Path("/path/to/new_package"),
}

write_cargo_config_toml(package_paths)

with config_file.open("r") as f:
content = toml.load(f)

# Existing config is preserved
assert content["build"]["target"] == "x86_64-unknown-linux-gnu"
assert content["build"]["jobs"] == 4

# Old crates-io patch is removed
assert "existing_package" not in content["patch"]["crates-io"]

# New crates-io patch is present
assert content["patch"]["crates-io"]["new_package"] == {
"path": "/path/to/new_package"
}


def test_write_cargo_config_toml_updates_existing_patch(temp_workspace):
"""Test that updating an existing patch overwrites it."""
config_dir = temp_workspace / ".cargo"
config_dir.mkdir(exist_ok=True)
config_file = config_dir / "config.toml"

existing_content = {
"patch": {
"crates-io": {
"my_package": {"path": "/old/path"},
}
}
}

with config_file.open("w") as f:
toml.dump(existing_content, f)

package_paths = {
"my_package": Path("/new/path"),
}

write_cargo_config_toml(package_paths)

with config_file.open("r") as f:
content = toml.load(f)

assert content["patch"]["crates-io"]["my_package"] == {"path": "/new/path"}
Loading