Skip to content

Commit 111ef2f

Browse files
committed
chore: update
1 parent 388d27d commit 111ef2f

File tree

2 files changed

+110
-6
lines changed

2 files changed

+110
-6
lines changed

platform_cli/groups/ros.py

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,14 @@
55

66

77
from platform_cli.groups.base import PlatformCliGroup
8-
from platform_cli.helpers import get_ros_env, echo, call, start_watcher
8+
from platform_cli.helpers import (
9+
get_ros_env,
10+
echo,
11+
call,
12+
start_watcher,
13+
get_changed_files,
14+
find_packages_for_changed_files,
15+
)
916

1017

1118
def get_ros_poetry_packages(path: Path) -> List[Path]:
@@ -23,6 +30,20 @@ def get_ros_poetry_packages(path: Path) -> List[Path]:
2330
return ros_poetry_packages
2431

2532

33+
def get_changed_packages(change_base: str) -> List[str]:
34+
"""Get list of ROS packages that have changes since base branch"""
35+
workspace_path = Path.cwd()
36+
37+
if not (workspace_path / ".git").exists():
38+
return []
39+
40+
changed_files = get_changed_files(change_base, workspace_path)
41+
if not changed_files:
42+
return []
43+
44+
return find_packages_for_changed_files(changed_files, workspace_path)
45+
46+
2647
def collect_xunit_xmls(destination: Path, package: str): # type: ignore
2748
"""Collects all pytest, gtest XML files from the test results"""
2849

@@ -101,30 +122,69 @@ def command():
101122
default=2,
102123
help="Number of times to retest until pass",
103124
)
125+
@click.option(
126+
"--changed",
127+
type=bool,
128+
is_flag=True,
129+
default=False,
130+
help="Only test packages with changes since base branch",
131+
)
132+
@click.option(
133+
"--change-base",
134+
type=str,
135+
default="main",
136+
help="Base branch to compare changes against (used with --changed)",
137+
)
138+
@click.option(
139+
"--include-dependents",
140+
type=bool,
141+
is_flag=True,
142+
default=False,
143+
help="Also test packages that depend on changed packages (used with --changed)",
144+
)
104145
@click.argument("args", nargs=-1)
105146
def test(
106147
package: str,
107148
results_dir: Path,
108149
watch: bool,
109150
build: bool,
110151
retest_until_pass: int,
152+
changed: bool,
153+
change_base: str,
154+
include_dependents: bool,
111155
args: List[str],
112156
):
113157
"""Runs colcon test on all ROS packages"""
114158

115159
env = get_ros_env()
116160
args_str = " ".join(args)
117161

118-
# Some args only apply to colcon test
119-
args_str_test = args_str
120-
args_str_build = args_str
162+
# Section 1: Determine packages to test
163+
packages_to_test = []
121164
if package:
122-
args_str_test += f" --packages-select {package}"
123-
args_str_build += f" --package {package}"
165+
packages_to_test = [package]
166+
elif changed:
167+
packages_to_test = get_changed_packages(change_base)
168+
169+
if not packages_to_test:
170+
return
171+
172+
# Section 2: Choose testing strategy
173+
args_str_test = args_str
174+
packages_str = " ".join(packages_to_test)
175+
176+
if include_dependents and changed:
177+
args_str_test += f" --packages-up-to {packages_str}"
178+
else:
179+
args_str_test += f" --packages-select {packages_str}"
124180

125181
def command():
126182
if build:
183+
args_str_build = args_str
184+
if package:
185+
args_str_build += f" --package {package}"
127186
call(" ".join(["platform ros build", args_str_build]))
187+
128188
p1 = call(
129189
" ".join(
130190
[

platform_cli/helpers.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,50 @@
1111
import signal
1212

1313

14+
def get_changed_files(base_branch: str = "main", cwd: Optional[Path] = None) -> List[Path]:
15+
"""Get list of files changed between current HEAD and base branch"""
16+
try:
17+
result = stdout_call(f"git diff --name-only {base_branch}...HEAD", cwd=cwd, abort=False)
18+
if not result.strip():
19+
return []
20+
21+
workspace = Path(cwd) if cwd else Path.cwd()
22+
return [
23+
(workspace / line.strip()).resolve()
24+
for line in result.strip().splitlines()
25+
if line.strip()
26+
]
27+
except Exception:
28+
return []
29+
30+
31+
def find_packages_for_changed_files(changed_files: List[Path], workspace_path: Path) -> List[str]:
32+
"""Find ROS packages that contain the changed files"""
33+
from platform_cli.groups.packaging import find_packages_with_colcon
34+
35+
if not changed_files:
36+
return []
37+
38+
try:
39+
all_packages = find_packages_with_colcon(workspace_path)
40+
if not all_packages:
41+
return []
42+
43+
affected_packages = set()
44+
for changed_file in changed_files:
45+
for package_name, package_path in all_packages.items():
46+
try:
47+
changed_file.resolve().relative_to(package_path.resolve())
48+
affected_packages.add(package_name)
49+
break
50+
except ValueError:
51+
continue
52+
53+
return list(affected_packages)
54+
except Exception:
55+
return []
56+
57+
1458
class FileSystemEventHandlerDebounced(FileSystemEventHandler):
1559
def __init__(
1660
self,

0 commit comments

Comments
 (0)