simfix 0.1.0__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. simfix-0.1.2/PKG-INFO +255 -0
  2. simfix-0.1.2/README.md +221 -0
  3. {simfix-0.1.0 → simfix-0.1.2}/pyproject.toml +1 -1
  4. {simfix-0.1.0 → simfix-0.1.2}/simfix/__init__.py +1 -1
  5. {simfix-0.1.0 → simfix-0.1.2}/simfix/cli.py +57 -1
  6. simfix-0.1.2/simfix/recommendations.py +131 -0
  7. simfix-0.1.2/simfix.egg-info/PKG-INFO +255 -0
  8. {simfix-0.1.0 → simfix-0.1.2}/simfix.egg-info/SOURCES.txt +1 -0
  9. {simfix-0.1.0 → simfix-0.1.2}/tests/test_basic.py +104 -1
  10. simfix-0.1.0/PKG-INFO +0 -286
  11. simfix-0.1.0/README.md +0 -252
  12. simfix-0.1.0/simfix.egg-info/PKG-INFO +0 -286
  13. {simfix-0.1.0 → simfix-0.1.2}/LICENSE +0 -0
  14. {simfix-0.1.0 → simfix-0.1.2}/setup.cfg +0 -0
  15. {simfix-0.1.0 → simfix-0.1.2}/simfix/analyzer.py +0 -0
  16. {simfix-0.1.0 → simfix-0.1.2}/simfix/cmake.py +0 -0
  17. {simfix-0.1.0 → simfix-0.1.2}/simfix/commands.py +0 -0
  18. {simfix-0.1.0 → simfix-0.1.2}/simfix/compatibility.py +0 -0
  19. {simfix-0.1.0 → simfix-0.1.2}/simfix/conda_environment.py +0 -0
  20. {simfix-0.1.0 → simfix-0.1.2}/simfix/conda_fixer.py +0 -0
  21. {simfix-0.1.0 → simfix-0.1.2}/simfix/cuda_docker.py +0 -0
  22. {simfix-0.1.0 → simfix-0.1.2}/simfix/docker_runner.py +0 -0
  23. {simfix-0.1.0 → simfix-0.1.2}/simfix/dockerfile.py +0 -0
  24. {simfix-0.1.0 → simfix-0.1.2}/simfix/fixer.py +0 -0
  25. {simfix-0.1.0 → simfix-0.1.2}/simfix/git_assets.py +0 -0
  26. {simfix-0.1.0 → simfix-0.1.2}/simfix/planner.py +0 -0
  27. {simfix-0.1.0 → simfix-0.1.2}/simfix/pypi.py +0 -0
  28. {simfix-0.1.0 → simfix-0.1.2}/simfix/pyproject.py +0 -0
  29. {simfix-0.1.0 → simfix-0.1.2}/simfix/python_requirements.py +0 -0
  30. {simfix-0.1.0 → simfix-0.1.2}/simfix/repo.py +0 -0
  31. {simfix-0.1.0 → simfix-0.1.2}/simfix/report.py +0 -0
  32. {simfix-0.1.0 → simfix-0.1.2}/simfix/ros_docker.py +0 -0
  33. {simfix-0.1.0 → simfix-0.1.2}/simfix/ros_package.py +0 -0
  34. {simfix-0.1.0 → simfix-0.1.2}/simfix/setup_py.py +0 -0
  35. {simfix-0.1.0 → simfix-0.1.2}/simfix/system.py +0 -0
  36. {simfix-0.1.0 → simfix-0.1.2}/simfix/system_docker.py +0 -0
  37. {simfix-0.1.0 → simfix-0.1.2}/simfix.egg-info/dependency_links.txt +0 -0
  38. {simfix-0.1.0 → simfix-0.1.2}/simfix.egg-info/entry_points.txt +0 -0
  39. {simfix-0.1.0 → simfix-0.1.2}/simfix.egg-info/requires.txt +0 -0
  40. {simfix-0.1.0 → simfix-0.1.2}/simfix.egg-info/top_level.txt +0 -0
simfix-0.1.2/PKG-INFO ADDED
@@ -0,0 +1,255 @@
1
+ Metadata-Version: 2.4
2
+ Name: simfix
3
+ Version: 0.1.2
4
+ Summary: A dependency checker and installation assistant for simulator repositories.
5
+ Author-email: Habib ur Rehmaan <h.rehmaan96@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/hrehmaan/simfix
8
+ Project-URL: Repository, https://github.com/hrehmaan/simfix
9
+ Project-URL: Issues, https://github.com/hrehmaan/simfix/issues
10
+ Keywords: simulator,dependencies,installation,docker,cuda,ros
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Operating System :: OS Independent
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: rich
24
+ Requires-Dist: typer
25
+ Requires-Dist: requests
26
+ Requires-Dist: packaging
27
+ Requires-Dist: pyyaml
28
+ Requires-Dist: uv
29
+ Provides-Extra: dev
30
+ Requires-Dist: pytest; extra == "dev"
31
+ Requires-Dist: pre-commit; extra == "dev"
32
+ Requires-Dist: ruff; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ # SimFix
36
+
37
+ SimFix is a command-line tool for diagnosing and fixing common setup problems in simulator repositories.
38
+
39
+ It inspects a project, detects dependency files, checks Python packages, reports system requirements, and suggests a safe installation plan.
40
+
41
+ ## Installation
42
+
43
+ Install SimFix from PyPI:
44
+
45
+ ```bash
46
+ pip install simfix
47
+ ```
48
+
49
+ Check that it installed correctly:
50
+
51
+ ```bash
52
+ simfix --version
53
+ ```
54
+
55
+ You can also check your system:
56
+
57
+ ```bash
58
+ simfix system
59
+ ```
60
+
61
+ ## Quick start
62
+
63
+ Analyze a simulator repository:
64
+
65
+ ```bash
66
+ simfix doctor <repo>
67
+ ```
68
+
69
+ Example:
70
+
71
+ ```bash
72
+ simfix doctor ../my_simulator_repo
73
+ ```
74
+
75
+ Apply supported automatic fixes:
76
+
77
+ ```bash
78
+ simfix fix <repo>
79
+ ```
80
+
81
+ Generate an installation plan:
82
+
83
+ ```bash
84
+ simfix plan <repo>
85
+ ```
86
+
87
+ Show suggested installation commands:
88
+
89
+ ```bash
90
+ simfix commands <repo>
91
+ ```
92
+
93
+ Generate a Markdown report:
94
+
95
+ ```bash
96
+ simfix doctor <repo> --report
97
+ ```
98
+
99
+ Analyze a GitHub repository directly:
100
+
101
+ ```bash
102
+ simfix doctor https://github.com/user/repository.git
103
+ ```
104
+
105
+ ## Environment recommendations
106
+
107
+ Some simulator projects require system-level or vendor-managed dependencies such as NVIDIA drivers, CUDA, ROS, Gazebo, Isaac Gym, or Isaac Sim. SimFix does not install these automatically because they depend on the operating system, hardware, driver compatibility, administrator permissions, and vendor installation steps.
108
+
109
+ Use:
110
+
111
+ ```bash
112
+ simfix recommendations <repo>
113
+ ```
114
+ ## Main commands
115
+
116
+ ```bash
117
+ simfix --version
118
+ simfix system
119
+ simfix doctor <repo>
120
+ simfix doctor <repo> --report
121
+ simfix recommendations <repo>
122
+ simfix fix <repo>
123
+ simfix analyze <repo>
124
+ simfix plan <repo>
125
+ simfix commands <repo>
126
+ ```
127
+
128
+ ## What SimFix can detect
129
+
130
+ SimFix currently detects:
131
+
132
+ * `requirements.txt`
133
+ * `setup.py`
134
+ * `pyproject.toml`
135
+ * `environment.yml` / `environment.yaml`
136
+ * `Dockerfile`
137
+ * `package.xml`
138
+ * `CMakeLists.txt`
139
+
140
+ ## What SimFix can fix
141
+
142
+ The `simfix fix` command currently supports:
143
+
144
+ * Resolving `requirements.txt` using `uv`
145
+ * Normalizing invalid pip syntax such as `package=version` to `package==version`
146
+ * Repairing clear dependency conflicts by removing direct conflicting pins and letting the resolver choose compatible versions
147
+ * Cleaning duplicate dependencies in `environment.yml`
148
+ * Creating CUDA/GPU Dockerfiles for GPU-based simulator projects
149
+ * Creating ROS Dockerfiles from `package.xml`
150
+ * Creating Docker run helper scripts
151
+ * Initializing Git submodules
152
+ * Pulling Git LFS assets when Git LFS is available
153
+
154
+ SimFix always modifies files in place, so review changes with:
155
+
156
+ ```bash
157
+ git diff
158
+ ```
159
+
160
+ ## Example
161
+
162
+ ```bash
163
+ simfix doctor ../my_simulator_repo
164
+ ```
165
+
166
+ Example output:
167
+
168
+ ```text
169
+ SimFix Doctor
170
+ Repository: /path/to/my_simulator_repo
171
+
172
+ Detected dependency files
173
+ requirements.txt: yes
174
+ setup.py: yes
175
+ Dockerfile: no
176
+
177
+ Detected ecosystem(s): python
178
+
179
+ PyPI check
180
+ numpy: found
181
+ matplotlib: found
182
+ isaacgym: not found
183
+
184
+ Recommendation:
185
+ Some dependencies are not available on PyPI.
186
+ Manual/vendor installation may be required.
187
+ ```
188
+
189
+ ## Important notes
190
+
191
+ SimFix does not install GPU drivers, CUDA drivers, ROS, Isaac Gym, Isaac Sim, or other vendor software automatically.
192
+
193
+ For GPU simulator projects, SimFix may create a CUDA Dockerfile, but your machine still needs a working NVIDIA driver and NVIDIA Container Toolkit to run GPU containers.
194
+
195
+ Some packages, such as NVIDIA Isaac Gym, are not available on PyPI and must be installed manually.
196
+
197
+ ## Development installation
198
+
199
+ For contributors, clone the repository:
200
+
201
+ ```bash
202
+ git clone https://github.com/hrehmaan/simfix.git
203
+ cd simfix
204
+ ```
205
+
206
+ Install in editable mode:
207
+
208
+ ```bash
209
+ python -m pip install -e ".[dev]"
210
+ ```
211
+
212
+ Install pre-commit hooks:
213
+
214
+ ```bash
215
+ pre-commit install
216
+ ```
217
+
218
+ Run tests:
219
+
220
+ ```bash
221
+ pytest
222
+ ```
223
+
224
+ Run all checks:
225
+
226
+ ```bash
227
+ pre-commit run --all-files
228
+ ```
229
+
230
+ ## Project status
231
+
232
+ SimFix is in early development.
233
+
234
+ The goal is to make simulator setup easier by combining repository analysis, system diagnostics, dependency checks, resolver-based repair, Docker guidance, and clear warnings for manual/vendor dependencies.
235
+
236
+ ## Contributing
237
+
238
+ Contributions are welcome.
239
+
240
+ Before opening a pull request, please first create an issue describing the bug, feature request, or improvement you want to work on. This helps avoid duplicate work and makes it easier to discuss the best solution before implementation.
241
+
242
+ Recommended contribution workflow:
243
+
244
+ ```bash
245
+ # 1. Create an issue on GitHub first
246
+ # 2. Fork the repository
247
+ # 3. Create a new branch
248
+ git checkout -b fix-or-feature-name
249
+
250
+ # 4. Make your changes
251
+ # 5. Run checks
252
+ pytest
253
+ pre-commit run --all-files
254
+
255
+ # 6. Open a pull request and link it to the issue
simfix-0.1.2/README.md ADDED
@@ -0,0 +1,221 @@
1
+ # SimFix
2
+
3
+ SimFix is a command-line tool for diagnosing and fixing common setup problems in simulator repositories.
4
+
5
+ It inspects a project, detects dependency files, checks Python packages, reports system requirements, and suggests a safe installation plan.
6
+
7
+ ## Installation
8
+
9
+ Install SimFix from PyPI:
10
+
11
+ ```bash
12
+ pip install simfix
13
+ ```
14
+
15
+ Check that it installed correctly:
16
+
17
+ ```bash
18
+ simfix --version
19
+ ```
20
+
21
+ You can also check your system:
22
+
23
+ ```bash
24
+ simfix system
25
+ ```
26
+
27
+ ## Quick start
28
+
29
+ Analyze a simulator repository:
30
+
31
+ ```bash
32
+ simfix doctor <repo>
33
+ ```
34
+
35
+ Example:
36
+
37
+ ```bash
38
+ simfix doctor ../my_simulator_repo
39
+ ```
40
+
41
+ Apply supported automatic fixes:
42
+
43
+ ```bash
44
+ simfix fix <repo>
45
+ ```
46
+
47
+ Generate an installation plan:
48
+
49
+ ```bash
50
+ simfix plan <repo>
51
+ ```
52
+
53
+ Show suggested installation commands:
54
+
55
+ ```bash
56
+ simfix commands <repo>
57
+ ```
58
+
59
+ Generate a Markdown report:
60
+
61
+ ```bash
62
+ simfix doctor <repo> --report
63
+ ```
64
+
65
+ Analyze a GitHub repository directly:
66
+
67
+ ```bash
68
+ simfix doctor https://github.com/user/repository.git
69
+ ```
70
+
71
+ ## Environment recommendations
72
+
73
+ Some simulator projects require system-level or vendor-managed dependencies such as NVIDIA drivers, CUDA, ROS, Gazebo, Isaac Gym, or Isaac Sim. SimFix does not install these automatically because they depend on the operating system, hardware, driver compatibility, administrator permissions, and vendor installation steps.
74
+
75
+ Use:
76
+
77
+ ```bash
78
+ simfix recommendations <repo>
79
+ ```
80
+ ## Main commands
81
+
82
+ ```bash
83
+ simfix --version
84
+ simfix system
85
+ simfix doctor <repo>
86
+ simfix doctor <repo> --report
87
+ simfix recommendations <repo>
88
+ simfix fix <repo>
89
+ simfix analyze <repo>
90
+ simfix plan <repo>
91
+ simfix commands <repo>
92
+ ```
93
+
94
+ ## What SimFix can detect
95
+
96
+ SimFix currently detects:
97
+
98
+ * `requirements.txt`
99
+ * `setup.py`
100
+ * `pyproject.toml`
101
+ * `environment.yml` / `environment.yaml`
102
+ * `Dockerfile`
103
+ * `package.xml`
104
+ * `CMakeLists.txt`
105
+
106
+ ## What SimFix can fix
107
+
108
+ The `simfix fix` command currently supports:
109
+
110
+ * Resolving `requirements.txt` using `uv`
111
+ * Normalizing invalid pip syntax such as `package=version` to `package==version`
112
+ * Repairing clear dependency conflicts by removing direct conflicting pins and letting the resolver choose compatible versions
113
+ * Cleaning duplicate dependencies in `environment.yml`
114
+ * Creating CUDA/GPU Dockerfiles for GPU-based simulator projects
115
+ * Creating ROS Dockerfiles from `package.xml`
116
+ * Creating Docker run helper scripts
117
+ * Initializing Git submodules
118
+ * Pulling Git LFS assets when Git LFS is available
119
+
120
+ SimFix always modifies files in place, so review changes with:
121
+
122
+ ```bash
123
+ git diff
124
+ ```
125
+
126
+ ## Example
127
+
128
+ ```bash
129
+ simfix doctor ../my_simulator_repo
130
+ ```
131
+
132
+ Example output:
133
+
134
+ ```text
135
+ SimFix Doctor
136
+ Repository: /path/to/my_simulator_repo
137
+
138
+ Detected dependency files
139
+ requirements.txt: yes
140
+ setup.py: yes
141
+ Dockerfile: no
142
+
143
+ Detected ecosystem(s): python
144
+
145
+ PyPI check
146
+ numpy: found
147
+ matplotlib: found
148
+ isaacgym: not found
149
+
150
+ Recommendation:
151
+ Some dependencies are not available on PyPI.
152
+ Manual/vendor installation may be required.
153
+ ```
154
+
155
+ ## Important notes
156
+
157
+ SimFix does not install GPU drivers, CUDA drivers, ROS, Isaac Gym, Isaac Sim, or other vendor software automatically.
158
+
159
+ For GPU simulator projects, SimFix may create a CUDA Dockerfile, but your machine still needs a working NVIDIA driver and NVIDIA Container Toolkit to run GPU containers.
160
+
161
+ Some packages, such as NVIDIA Isaac Gym, are not available on PyPI and must be installed manually.
162
+
163
+ ## Development installation
164
+
165
+ For contributors, clone the repository:
166
+
167
+ ```bash
168
+ git clone https://github.com/hrehmaan/simfix.git
169
+ cd simfix
170
+ ```
171
+
172
+ Install in editable mode:
173
+
174
+ ```bash
175
+ python -m pip install -e ".[dev]"
176
+ ```
177
+
178
+ Install pre-commit hooks:
179
+
180
+ ```bash
181
+ pre-commit install
182
+ ```
183
+
184
+ Run tests:
185
+
186
+ ```bash
187
+ pytest
188
+ ```
189
+
190
+ Run all checks:
191
+
192
+ ```bash
193
+ pre-commit run --all-files
194
+ ```
195
+
196
+ ## Project status
197
+
198
+ SimFix is in early development.
199
+
200
+ The goal is to make simulator setup easier by combining repository analysis, system diagnostics, dependency checks, resolver-based repair, Docker guidance, and clear warnings for manual/vendor dependencies.
201
+
202
+ ## Contributing
203
+
204
+ Contributions are welcome.
205
+
206
+ Before opening a pull request, please first create an issue describing the bug, feature request, or improvement you want to work on. This helps avoid duplicate work and makes it easier to discuss the best solution before implementation.
207
+
208
+ Recommended contribution workflow:
209
+
210
+ ```bash
211
+ # 1. Create an issue on GitHub first
212
+ # 2. Fork the repository
213
+ # 3. Create a new branch
214
+ git checkout -b fix-or-feature-name
215
+
216
+ # 4. Make your changes
217
+ # 5. Run checks
218
+ pytest
219
+ pre-commit run --all-files
220
+
221
+ # 6. Open a pull request and link it to the issue
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simfix"
7
- version = "0.1.0"
7
+ version = "0.1.2"
8
8
  description = "A dependency checker and installation assistant for simulator repositories."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,3 +1,3 @@
1
1
  """SimFix package."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.1.2"
@@ -16,7 +16,7 @@ from simfix.pypi import check_pypi_packages
16
16
  from simfix.repo import clone_repo, is_git_url
17
17
  from simfix.report import generate_markdown_report, write_markdown_report
18
18
  from simfix.system import get_system_info
19
-
19
+ from simfix.recommendations import generate_recommendations
20
20
 
21
21
  console = Console()
22
22
 
@@ -58,6 +58,33 @@ def _resolve_repo_path(repo: str) -> Path:
58
58
  return Path(repo)
59
59
 
60
60
 
61
+ def print_recommendations_table(recommendations: list) -> None:
62
+ """Print system and vendor dependency recommendations."""
63
+ if not recommendations:
64
+ console.print(
65
+ "[green]No additional system or vendor recommendations found.[/green]"
66
+ )
67
+ return
68
+
69
+ table = Table(title="Environment compatibility recommendations")
70
+ table.add_column("Category")
71
+ table.add_column("Status")
72
+ table.add_column("Title")
73
+ table.add_column("Reason")
74
+ table.add_column("Suggestion")
75
+
76
+ for recommendation in recommendations:
77
+ table.add_row(
78
+ recommendation.category,
79
+ recommendation.status,
80
+ recommendation.title,
81
+ recommendation.reason,
82
+ recommendation.suggestion,
83
+ )
84
+
85
+ console.print(table)
86
+
87
+
61
88
  @app.command()
62
89
  def analyze(repo: str) -> None:
63
90
  """Analyze repository dependency files without system diagnostics."""
@@ -84,6 +111,23 @@ def analyze(repo: str) -> None:
84
111
  console.print(f"[bold]Detected ecosystem(s):[/bold] {ecosystems}")
85
112
 
86
113
 
114
+ @app.command()
115
+ def recommendations(repo: str) -> None:
116
+ """Show environment compatibility and manual dependency guidance."""
117
+ repo_path = Path(repo).expanduser().resolve()
118
+ analysis = analyze_repo(repo_path)
119
+
120
+ repo_recommendations = generate_recommendations(
121
+ dependencies=analysis.all_python_dependencies,
122
+ detected_ecosystems=analysis.detected_ecosystems,
123
+ )
124
+
125
+ console.print("[bold]SimFix Recommendations[/bold]")
126
+ console.print(f"Repository: {repo_path}")
127
+
128
+ print_recommendations_table(repo_recommendations)
129
+
130
+
87
131
  @app.command()
88
132
  def plan(repo: str) -> None:
89
133
  """Generate a recommended installation plan for a repository."""
@@ -358,6 +402,18 @@ def doctor(
358
402
 
359
403
  console.print(warning_table)
360
404
 
405
+ repo_recommendations = generate_recommendations(
406
+ dependencies=analysis.all_python_dependencies,
407
+ detected_ecosystems=analysis.detected_ecosystems,
408
+ )
409
+
410
+ if repo_recommendations:
411
+ console.print()
412
+ console.print(
413
+ "[yellow]System/vendor recommendations found.[/yellow] "
414
+ f"Run: simfix recommendations {repo_path}"
415
+ )
416
+
361
417
  if report:
362
418
  report_text = generate_markdown_report(
363
419
  analysis=analysis,
@@ -0,0 +1,131 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+
5
+
6
+ @dataclass(frozen=True)
7
+ class Recommendation:
8
+ """A safe recommendation for a system or vendor dependency."""
9
+
10
+ category: str
11
+ title: str
12
+ status: str
13
+ reason: str
14
+ suggestion: str
15
+
16
+
17
+ def generate_recommendations(
18
+ dependencies: list[str],
19
+ detected_ecosystems: list[str],
20
+ ) -> list[Recommendation]:
21
+ """Generate safe system and vendor dependency recommendations.
22
+
23
+ This function does not install drivers, ROS, CUDA, or vendor tools.
24
+ It only detects likely requirements and returns guidance.
25
+ """
26
+ recommendations: list[Recommendation] = []
27
+
28
+ normalized_dependencies = [dependency.lower() for dependency in dependencies]
29
+
30
+ normalized_ecosystems = [ecosystem.lower() for ecosystem in detected_ecosystems]
31
+
32
+ has_isaacgym = any(
33
+ "isaacgym" in dependency for dependency in normalized_dependencies
34
+ )
35
+ has_isaacsim = any(
36
+ "isaacsim" in dependency or "omni.isaac" in dependency
37
+ for dependency in normalized_dependencies
38
+ )
39
+ has_cuda_dependency = any(
40
+ _has_cuda_keyword(dependency) for dependency in normalized_dependencies
41
+ )
42
+ has_ros = "ros" in normalized_ecosystems
43
+
44
+ if has_isaacgym:
45
+ recommendations.append(
46
+ Recommendation(
47
+ category="Vendor-managed dependency",
48
+ title="NVIDIA Isaac Gym required",
49
+ status="Manual installation required",
50
+ reason=(
51
+ "The dependency 'isaacgym' was detected, but it is not "
52
+ "available as a normal PyPI package."
53
+ ),
54
+ suggestion=(
55
+ "Install NVIDIA Isaac Gym manually in a compatible Linux "
56
+ "environment with NVIDIA GPU support. If the local machine "
57
+ "is not suitable, use an HPC GPU node or cloud GPU instance."
58
+ ),
59
+ )
60
+ )
61
+
62
+ if has_isaacsim:
63
+ recommendations.append(
64
+ Recommendation(
65
+ category="Vendor-managed dependency",
66
+ title="NVIDIA Isaac Sim required",
67
+ status="Manual installation required",
68
+ reason=(
69
+ "Isaac Sim or omni.isaac dependencies were detected. "
70
+ "These are NVIDIA-managed dependencies."
71
+ ),
72
+ suggestion=(
73
+ "Install Isaac Sim using NVIDIA's official installation "
74
+ "method. Use a supported system with compatible NVIDIA GPU "
75
+ "drivers."
76
+ ),
77
+ )
78
+ )
79
+
80
+ if has_isaacgym or has_isaacsim or has_cuda_dependency:
81
+ recommendations.append(
82
+ Recommendation(
83
+ category="GPU/CUDA",
84
+ title="CUDA-compatible environment recommended",
85
+ status="Check required",
86
+ reason=(
87
+ "GPU/CUDA-related dependencies were detected in the " "repository."
88
+ ),
89
+ suggestion=(
90
+ "Use a compatible Linux/NVIDIA GPU environment. If the "
91
+ "local GPU is not CUDA-compatible, consider a Docker setup "
92
+ "on a compatible machine, an HPC GPU node, a cloud GPU "
93
+ "instance, or CPU-only mode if the simulator supports it."
94
+ ),
95
+ )
96
+ )
97
+
98
+ if has_ros:
99
+ recommendations.append(
100
+ Recommendation(
101
+ category="ROS",
102
+ title="ROS environment required",
103
+ status="Manual installation required",
104
+ reason="ROS package files were detected in the repository.",
105
+ suggestion=(
106
+ "Use a matching ROS Docker image or install the correct "
107
+ "ROS distribution manually. For ROS 1/catkin projects, "
108
+ "ROS Noetic on Ubuntu 20.04 is commonly used. For ROS "
109
+ "2/ament projects, ROS Humble on Ubuntu 22.04 is commonly "
110
+ "used."
111
+ ),
112
+ )
113
+ )
114
+
115
+ return recommendations
116
+
117
+
118
+ def _has_cuda_keyword(dependency: str) -> bool:
119
+ """Return True if a dependency suggests GPU/CUDA requirements."""
120
+ cuda_keywords = [
121
+ "cuda",
122
+ "cudnn",
123
+ "cupy",
124
+ "pytorch3d",
125
+ "onnxruntime-gpu",
126
+ "tensorflow-gpu",
127
+ "jax[cuda",
128
+ "numba.cuda",
129
+ ]
130
+
131
+ return any(keyword in dependency for keyword in cuda_keywords)