ros-dds-manager 0.1.0__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 (32) hide show
  1. ros_dds_manager-0.1.0/.env.example +2 -0
  2. ros_dds_manager-0.1.0/.gitignore +10 -0
  3. ros_dds_manager-0.1.0/.python-version +1 -0
  4. ros_dds_manager-0.1.0/AGENTS.md +124 -0
  5. ros_dds_manager-0.1.0/CHANGELOG.md +48 -0
  6. ros_dds_manager-0.1.0/CONTRIBUTING.md +31 -0
  7. ros_dds_manager-0.1.0/LICENSE +122 -0
  8. ros_dds_manager-0.1.0/PKG-INFO +234 -0
  9. ros_dds_manager-0.1.0/README.md +207 -0
  10. ros_dds_manager-0.1.0/SECURITY.md +16 -0
  11. ros_dds_manager-0.1.0/pyproject.toml +59 -0
  12. ros_dds_manager-0.1.0/src/ros_dds_manager/__init__.py +62 -0
  13. ros_dds_manager-0.1.0/src/ros_dds_manager/commands/config_cmd.py +131 -0
  14. ros_dds_manager-0.1.0/src/ros_dds_manager/commands/doctor_cmd.py +157 -0
  15. ros_dds_manager-0.1.0/src/ros_dds_manager/commands/profile_cmd.py +508 -0
  16. ros_dds_manager-0.1.0/src/ros_dds_manager/commands/run_cmd.py +47 -0
  17. ros_dds_manager-0.1.0/src/ros_dds_manager/config_mgr.py +138 -0
  18. ros_dds_manager-0.1.0/src/ros_dds_manager/errors.py +61 -0
  19. ros_dds_manager-0.1.0/src/ros_dds_manager/generator.py +37 -0
  20. ros_dds_manager-0.1.0/src/ros_dds_manager/main.py +113 -0
  21. ros_dds_manager-0.1.0/src/ros_dds_manager/models.py +132 -0
  22. ros_dds_manager-0.1.0/src/ros_dds_manager/network.py +108 -0
  23. ros_dds_manager-0.1.0/src/ros_dds_manager/storage.py +181 -0
  24. ros_dds_manager-0.1.0/src/ros_dds_manager/templates/cyclonedds.xml.j2 +43 -0
  25. ros_dds_manager-0.1.0/src/ros_dds_manager/templates/fastdds.xml.j2 +85 -0
  26. ros_dds_manager-0.1.0/tests/test_cli.py +222 -0
  27. ros_dds_manager-0.1.0/tests/test_config.py +41 -0
  28. ros_dds_manager-0.1.0/tests/test_generator.py +76 -0
  29. ros_dds_manager-0.1.0/tests/test_models.py +56 -0
  30. ros_dds_manager-0.1.0/tests/test_smoke.py +54 -0
  31. ros_dds_manager-0.1.0/tests/test_storage.py +71 -0
  32. ros_dds_manager-0.1.0/uv.lock +274 -0
@@ -0,0 +1,2 @@
1
+ ROS_DDS_MANAGER_APP__DEFAULT_VENDOR=cyclonedds
2
+ ROS_DDS_MANAGER_LOGGING__LEVEL=INFO
@@ -0,0 +1,10 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .coverage
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .env
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,124 @@
1
+ # AGENTS.md
2
+
3
+ `ros-dds-manager` 프로젝트에 기여하는 AI 코딩 에이전트 및 개발자를 위한 아키텍처 및 개발 지침서입니다.
4
+
5
+ ---
6
+
7
+ ## 1. 프로젝트 아키텍처 및 디렉토리 구조
8
+
9
+ ```
10
+ ros-dds-manager/
11
+ ├── src/ros_dds_manager/
12
+ │ ├── __init__.py # 공개 API 및 라이브러리 인터페이스 (모듈 export 정의)
13
+ │ ├── errors.py # 도메인 예외 클래스 및 표준 종료 코드 (clig.dev 준수)
14
+ │ ├── main.py # wpycli 기반 CLI 엔트리포인트 및 런타임 설정
15
+ │ ├── models.py # DDSProfile, DDSVendor 등 불변/데이터 클래스
16
+ │ ├── generator.py # Jinja2 기반 DDS XML 렌더링 및 문법 검증
17
+ │ ├── templates/ # cyclonedds.xml.j2, fastdds.xml.j2 템플릿
18
+ │ ├── storage.py # 프로파일 파일 I/O, 활성 상태 및 current.sh 관리
19
+ │ ├── network.py # 호스트 네트워크 인터페이스/IP 감지 (Linux ip -j addr)
20
+ │ ├── config_mgr.py # 앱 설정(config.toml) 입출력 및 키-값 파서
21
+ │ └── commands/ # 서브커맨드 모듈 분리
22
+ │ ├── profile_cmd.py # list, show, switch/use, env, generate, init, delete
23
+ │ ├── doctor_cmd.py # doctor (진단 리포트)
24
+ │ ├── run_cmd.py # run (서브프로세스 환경 주입 실행)
25
+ │ └── config_cmd.py # config (init, show, path, set, get)
26
+ ├── tests/ # pytest 테스트 스위트
27
+ │ ├── test_cli.py # CLI 엔드투엔드 통합 테스트
28
+ │ ├── test_config.py # 설정 관리 단위 테스트
29
+ │ ├── test_generator.py # XML 템플릿 렌더링 및 파싱 테스트
30
+ │ ├── test_models.py # 모델 직렬화/역직렬화 및 환경변수 계산 테스트
31
+ │ └── test_storage.py # 파일시스템 저장소 생명주기 테스트
32
+ ├── pyproject.toml # 프로젝트 메타데이터, 의존성, ruff 설정
33
+ ├── CHANGELOG.md # Keep a Changelog 규격 변경 이력
34
+ └── README.md # 사용자용 매뉴얼 및 시나리오 가이드
35
+ ```
36
+
37
+ ---
38
+
39
+ ## 2. 개발 및 TDD 원칙 (Test-Driven Development)
40
+
41
+ 1. **테스트 우선/동반 (Test-First / Co-evolution)**:
42
+ - 새로운 기능이나 버그 수정을 진행할 때는 반드시 `tests/` 디렉토리에 대응하는 단위 또는 통합 테스트를 추가/보완해야 합니다.
43
+ - 테스트 실행:
44
+ ```bash
45
+ uv run pytest
46
+ ```
47
+ 2. **엄격한 린트 및 코드 스타일 준수**:
48
+ - `ruff` 검사를 통과해야 하며, 불필요한 import나 미사용 변수가 없어야 합니다.
49
+ - 린트 검사 및 자동 수정:
50
+ ```bash
51
+ uv run ruff check .
52
+ uv run ruff check --fix .
53
+ ```
54
+ 3. **간결하고 명확한 주석**:
55
+ - 코드에 불필요한 개발자 독백이나 장황한 설명을 남기지 마세요.
56
+ - 복잡한 도메인 지식(예: Fast-DDS discovery locator, CycloneDDS buffer watermark)에 대해서만 명확한 인라인 주석을 작성하세요.
57
+
58
+ ---
59
+
60
+ ## 3. CLI 가이드라인 준수 원칙 ([clig.dev](https://clig.dev/))
61
+
62
+ 다른 에이전트가 CLI 인터페이스를 확장할 때 다음 규칙을 반드시 준수해야 합니다:
63
+
64
+ ### 3.1 입력 및 대화형 제어 (Input & Non-interactive safety)
65
+ - `init` 마법사 같은 대화형 프롬프트는 반드시 `sys.stdin.isatty() and sys.stdout.isatty()` 상태 및 `--no-input` 플래그를 검사해야 합니다.
66
+ - TTY가 아니거나 `--no-input`이 켜져 있는 환경에서는 무한 대기하지 말고 `EXIT_USAGE (2)`로 즉시 실패하며, 비대화형 대체 명령어(`generate` 등)를 안내해야 합니다.
67
+
68
+ ### 3.2 파괴적 작업 확인 (Destructive Safety)
69
+ - `delete` 등의 파괴적 작업은 `--yes (-y)` 플래그를 제공해야 합니다.
70
+ - 비대화형 환경에서 `--yes`가 누락된 채 파괴적 명령이 실행되면 `EXIT_USAGE (2)`로 안전하게 차단해야 합니다.
71
+
72
+ ### 3.3 출력 스트림 분리 (Output Separation)
73
+ - **stdout**: 순수 데이터, 명령어 처리 결과, `--json` 출력, `env`의 export 구문.
74
+ - **stderr**: 에러 메시지, 경고, 진단 안내 문구.
75
+ - 스크립팅 자동화를 위해 주요 조회 명령어(`list`, `show`, `doctor`)에 `--json (-j)` 플래그를 지원해야 합니다.
76
+ - `-q, --quiet` 플래그 지정 시 팁(tip)이나 부가 배너 출력을 억제합니다.
77
+
78
+ ### 3.4 표준 종료 코드 (Standard Exit Codes)
79
+ `ros_dds_manager.errors`에 정의된 상수를 일관되게 반환하세요:
80
+ - `EXIT_SUCCESS = 0`: 작업 성공
81
+ - `EXIT_ERROR = 1`: 런타임/운영 오류 (프로파일 없음, 파일 쓰기 실패 등)
82
+ - `EXIT_USAGE = 2`: 잘못된 인수, 비대화형 입력 누락, 확인 플래그 미지정
83
+ - `EXIT_NOT_FOUND = 127`: `run` 명령에서 대상 실행 파일 미발견
84
+ - `EXIT_INTERRUPT = 130`: SIGINT (Ctrl+C)
85
+
86
+ ---
87
+
88
+ ## 4. 신규 DDS 벤더 추가 절차
89
+
90
+ 새로운 DDS 벤더(예: RTI Connext DDS, GurumDDS)를 추가하려면:
91
+ 1. `src/ros_dds_manager/models.py`:
92
+ - `DDSVendor` 열거형에 새 벤더 추가
93
+ - `rmw_implementation` 및 `get_env_vars`에 필요한 환경변수(예: `NDDS_QOS_PROFILES`) 매핑 추가
94
+ 2. `src/ros_dds_manager/templates/`:
95
+ - `<vendor>.xml.j2` Jinja2 템플릿 파일 생성
96
+ 3. `src/ros_dds_manager/commands/profile_cmd.py`:
97
+ - `build_generate_command()`에 해당 벤더 전용 서브커맨드 및 플래그 추가
98
+ 4. `tests/`:
99
+ - `test_generator.py`에 XML 렌더링 테스트 추가
100
+ - `test_cli.py`에 CLI 생성/활성화 테스트 추가
101
+
102
+ ---
103
+
104
+ ## 5. 릴리스 및 PyPI 배포
105
+
106
+ 버전의 단일 소스는 `src/ros_dds_manager/__init__.py`의 `__version__`이다. `pyproject.toml`은 `dynamic = ["version"]` + `[tool.hatch.version]`로 이 값을 읽는다. **버전을 다른 곳에 중복 기재하지 마세요.**
107
+
108
+ 릴리스 절차:
109
+ 1. `CHANGELOG.md`의 `[Unreleased]` 항목을 새 버전 섹션으로 이동.
110
+ 2. `__version__` 갱신.
111
+ 3. `uv run ruff check . && uv run pytest` 통과 확인.
112
+ 4. `uv build && uvx twine check dist/*` 통과 확인.
113
+ 5. `v<version>` 형식의 태그를 push하면 `.github/workflows/release.yml`이 PyPI로 게시한다.
114
+
115
+ 배포는 PyPI Trusted Publishing(OIDC)으로만 수행하며, 저장소에 API 토큰을 두지 않는다. 워크플로는 다음 등록 정보와 정확히 일치해야 한다:
116
+
117
+ | 항목 | 값 |
118
+ | --- | --- |
119
+ | Owner | `wkqco33` |
120
+ | Repository | `ros-dds-manager` |
121
+ | Workflow name | `release.yml` |
122
+ | Environment name | `pypi` |
123
+
124
+ 태그 버전과 패키지 버전이 다르면 워크플로가 게시 전에 실패한다.
@@ -0,0 +1,48 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-09-22
11
+
12
+ ### Packaging & Distribution
13
+ - PyPI 배포 메타데이터 정비: PEP 639 라이선스 표현(`Apache-2.0`), `authors`, `keywords`, `classifiers`, `[project.urls]` 추가.
14
+ - 버전을 `src/ros_dds_manager/__init__.py` 단일 소스로 통합 (`dynamic = ["version"]` + `[tool.hatch.version]`). CLI 버전도 동일 상수를 참조.
15
+ - sdist에서 개발용 `config.toml` 및 CI 워크플로를 제외.
16
+ - Trusted Publishing(OIDC) 기반 `release.yml` 워크플로 추가 (태그-버전 일치 검증 → 린트/테스트 → 빌드 → PyPI 게시).
17
+ - CI를 Python 3.12/3.13 매트릭스로 확장.
18
+ - README에 PyPI 설치 안내 및 배지 추가.
19
+
20
+ ### Added
21
+ - **Core Models & Generator**:
22
+ - `DDSProfile` and `DDSVendor` supporting `cyclonedds` and `fastdds`.
23
+ - Jinja2 template rendering for CycloneDDS (`cyclonedds.xml.j2`) and Fast-DDS (`fastdds.xml.j2`).
24
+ - Strict XML syntax validation using `xml.etree.ElementTree`.
25
+ - **Profile Management**:
26
+ - `ros-dds-manager list`: Table and machine-readable `--json`, `--plain` output.
27
+ - `ros-dds-manager show [name]`: Metadata, XML preview, and environment variables inspection.
28
+ - `ros-dds-manager switch <name>` / `use <name>`: Profile activation and symlink management (`current.sh`, `current.xml`).
29
+ - `ros-dds-manager env [name]`: Outputs sourceable shell `export` statements (`--unset` supported).
30
+ - `ros-dds-manager delete <name>`: Deletes profile with interactive confirmation or `--yes` flag.
31
+ - `ros-dds-manager generate <vendor>`: CLI flags generator with `--dry-run` preview.
32
+ - `ros-dds-manager init [name]`: Interactive wizard with auto-detected network interfaces.
33
+ - `ros-dds-manager run <profile> -- <command...>`: Subprocess execution with profile environment.
34
+ - Short command alias `rddm` registered alongside `ros-dds-manager`.
35
+ - **Config Management**:
36
+ - `ros-dds-manager config init`: Initializes global or local `config.toml`.
37
+ - `ros-dds-manager config show`: Displays active configuration (`--json` supported).
38
+ - `ros-dds-manager config path`: Resolves configuration file location.
39
+ - `ros-dds-manager config set <key> <value>`: Updates configuration keys.
40
+ - `ros-dds-manager config get <key>`: Reads specific configuration value.
41
+ - **Diagnostics & Network Discovery**:
42
+ - `ros-dds-manager doctor`: Full health check (`--json` supported) for ROS distro, active profile, environment variables, and network cards.
43
+ - Network interface inspection utility (`network.py`) using Linux `ip -j addr`.
44
+ - **CLI Standards (clig.dev) Compliance**:
45
+ - Standard exit codes (0: success, 1: error, 2: usage/input required, 127: not found, 130: interrupt).
46
+ - TTY and non-interactive `--no-input` safety.
47
+ - XDG Base Directory specification compliance (`XDG_CONFIG_HOME`).
48
+ - Typed domain exceptions in `errors.py`.
@@ -0,0 +1,31 @@
1
+ # Contributing to ros-dds-manager
2
+
3
+ `ros-dds-manager` 프로젝트에 관심을 가져주셔서 감사합니다! 기여를 위한 지침은 다음과 같습니다.
4
+
5
+ ---
6
+
7
+ ## 개발 환경 설정
8
+
9
+ 1. **저장소 클론 및 패키지 설치**:
10
+ ```bash
11
+ uv sync --group dev
12
+ ```
13
+
14
+ 2. **테스트 실행**:
15
+ ```bash
16
+ uv run pytest
17
+ ```
18
+
19
+ 3. **린트 및 코드 스타일 검사**:
20
+ ```bash
21
+ uv run ruff check .
22
+ uv run ruff check --fix .
23
+ ```
24
+
25
+ ---
26
+
27
+ ## 기여 가이드라인
28
+
29
+ - **TDD (테스트 주도 개발)**: 버그 수정이나 새 기능 추가 시 항상 `tests/` 디렉토리에 테스트 코드를 포함하세요.
30
+ - **CLI 원칙 준수**: 대화형 입력, JSON 출력, 종료 코드 등 [clig.dev](https://clig.dev/) 원칙과 `AGENTS.md` 지침을 따르세요.
31
+ - **Commit 메시지**: Conventional Commits (예: `feat: ...`, `fix: ...`, `docs: ...`, `test: ...`) 형식을 권장합니다.
@@ -0,0 +1,122 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work.
38
+
39
+ "Derivative Works" shall mean any work, whether in Source or Object
40
+ form, that is based on (or derived from) the Work and for which the
41
+ editorial revisions, annotations, elaborations, or other modifications
42
+ represent, as a whole, an original work of authorship. For the purposes
43
+ of this License, Derivative Works shall not include works that remain
44
+ separable from, or merely link (or bind by name) to the interfaces of,
45
+ the Work and Derivative Works thereof.
46
+
47
+ "Contribution" shall mean any work of authorship, including
48
+ the original version of the Work and any modifications or additions
49
+ to that Work or Derivative Works thereof, that is intentionally
50
+ submitted to Licensor for inclusion in the Work by the copyright owner
51
+ or by an individual or Legal Entity authorized to submit on behalf of
52
+ the copyright owner.
53
+
54
+ "Contributor" shall mean Licensor and any individual or Legal Entity
55
+ on behalf of whom a Contribution has been received by Licensor and
56
+ subsequently incorporated within the Work.
57
+
58
+ 2. Grant of Copyright License. Subject to the terms and conditions of
59
+ this License, each Contributor hereby grants to You a perpetual,
60
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
61
+ copyright license to reproduce, prepare Derivative Works of,
62
+ publicly display, publicly perform, sublicense, and distribute the
63
+ Work and such Derivative Works in Source or Object form.
64
+
65
+ 3. Grant of Patent License. Subject to the terms and conditions of
66
+ this License, each Contributor hereby grants to You a perpetual,
67
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
68
+ (except as stated in this section) patent license to make, have made,
69
+ use, offer to sell, sell, import, and otherwise transfer the Work.
70
+
71
+ 4. Redistribution. You may reproduce and distribute copies of the
72
+ Work or Derivative Works thereof in any medium, with or without
73
+ modifications, and in Source or Object form, provided that You
74
+ meet the following conditions:
75
+
76
+ (a) You must give any other recipients of the Work or
77
+ Derivative Works a copy of this License; and
78
+
79
+ (b) You must cause any modified files to carry prominent notices
80
+ stating that You changed the files; and
81
+
82
+ (c) You must retain, in the Source form of any Derivative Works
83
+ that You distribute, all copyright, patent, trademark, and
84
+ attribution notices from the Source form of the Work; and
85
+
86
+ (d) If the Work includes a "NOTICE" text file as part of its
87
+ distribution, then any Derivative Works that You distribute must
88
+ include a readable copy of the attribution notices contained
89
+ within such NOTICE file.
90
+
91
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
92
+ any Contribution intentionally submitted for inclusion in the Work
93
+ by You to the Licensor shall be under the terms and conditions of
94
+ this License, without any additional terms or conditions.
95
+
96
+ 6. Trademarks. This License does not grant permission to use the trade
97
+ names, trademarks, service marks, or product names of the Licensor,
98
+ except as required for reasonable and customary use in describing the
99
+ origin of the Work and reproducing the content of the NOTICE file.
100
+
101
+ 7. Disclaimer of Warranty. Unless required by applicable law or
102
+ agreed to in writing, Licensor provides the Work (and each
103
+ Contributor provides its Contributions) on an "AS IS" BASIS,
104
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
105
+ implied, including, without limitation, any warranties or conditions
106
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
107
+ PARTICULAR PURPOSE.
108
+
109
+ 8. Limitation of Liability. In no event and under no legal theory,
110
+ whether in tort (including negligence), contract, or otherwise,
111
+ unless required by applicable law (such as deliberate and grossly
112
+ negligent acts) or agreed to in writing, shall any Contributor be
113
+ liable to You for damages, including any direct, indirect, special,
114
+ incidental, or consequential damages of any character arising as a
115
+ result of this License or out of the use or inability to use the
116
+ Work.
117
+
118
+ 9. Accepting Warranty or Additional Liability. While redistributing
119
+ the Work or Derivative Works thereof, You may choose to offer,
120
+ and charge a fee for, acceptance of support, warranty, indemnity,
121
+ or other liability obligations and/or rights consistent with this
122
+ License.
@@ -0,0 +1,234 @@
1
+ Metadata-Version: 2.5
2
+ Name: ros-dds-manager
3
+ Version: 0.1.0
4
+ Summary: ROS 2 DDS(CycloneDDS, Fast-DDS) XML 설정 생성 및 프로파일 전환 CLI
5
+ Project-URL: Homepage, https://github.com/wkqco33/ros-dds-manager
6
+ Project-URL: Repository, https://github.com/wkqco33/ros-dds-manager
7
+ Project-URL: Issues, https://github.com/wkqco33/ros-dds-manager/issues
8
+ Project-URL: Changelog, https://github.com/wkqco33/ros-dds-manager/blob/main/CHANGELOG.md
9
+ Author-email: wkqco33 <wkqco33@users.noreply.github.com>
10
+ License-Expression: Apache-2.0
11
+ License-File: LICENSE
12
+ Keywords: cli,cyclonedds,dds,fastdds,rmw,robotics,ros2
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Operating System :: POSIX :: Linux
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Scientific/Engineering
20
+ Classifier: Topic :: System :: Networking
21
+ Requires-Python: >=3.12
22
+ Requires-Dist: jinja2>=3.1.6
23
+ Requires-Dist: wpycli>=0.3.2
24
+ Requires-Dist: wpyconf
25
+ Requires-Dist: wpylog
26
+ Description-Content-Type: text/markdown
27
+
28
+ # ros-dds-manager (`rddm`)
29
+
30
+ [![PyPI version](https://img.shields.io/pypi/v/ros-dds-manager.svg)](https://pypi.org/project/ros-dds-manager/)
31
+ [![Python versions](https://img.shields.io/pypi/pyversions/ros-dds-manager.svg)](https://pypi.org/project/ros-dds-manager/)
32
+ [![License](https://img.shields.io/pypi/l/ros-dds-manager.svg)](https://github.com/wkqco33/ros-dds-manager/blob/main/LICENSE)
33
+ [![CI](https://github.com/wkqco33/ros-dds-manager/actions/workflows/ci.yml/badge.svg)](https://github.com/wkqco33/ros-dds-manager/actions/workflows/ci.yml)
34
+
35
+ ROS 2 환경에서 DDS(CycloneDDS, Fast-DDS 등)의 복잡한 XML 설정 파일을 자동으로 생성하고, 상황에 맞추어 손쉽게 전환/적용할 수 있는 CLI 도구 및 Python 라이브러리입니다.
36
+
37
+ > **Tip**: 긴 명령어 대신 짧은 단축 별칭 **`rddm`**을 사용할 수 있습니다. (`ros-dds-manager`와 완전히 동일)
38
+ > ```bash
39
+ > rddm list
40
+ > rddm switch sim-local
41
+ > ```
42
+
43
+ ---
44
+
45
+ ## 📦 설치 (Installation)
46
+
47
+ PyPI에서 바로 설치합니다. Python 3.12 이상이 필요합니다.
48
+
49
+ ```bash
50
+ # CLI 도구로 설치 (권장)
51
+ uv tool install ros-dds-manager
52
+ # 또는
53
+ pipx install ros-dds-manager
54
+
55
+ # 라이브러리로 사용
56
+ pip install ros-dds-manager
57
+ ```
58
+
59
+ 설치 후 `ros-dds-manager` 또는 `rddm` 명령을 사용할 수 있습니다.
60
+
61
+ ```bash
62
+ ros-dds-manager --version
63
+ rddm doctor
64
+ ```
65
+
66
+ <details>
67
+ <summary>소스에서 개발 환경 구성</summary>
68
+
69
+ ```bash
70
+ git clone https://github.com/wkqco33/ros-dds-manager.git
71
+ cd ros-dds-manager
72
+ uv sync
73
+ uv run rddm --help
74
+ ```
75
+
76
+ </details>
77
+
78
+ ---
79
+
80
+ ## 🚀 빠른 시작 (Quick Start)
81
+
82
+ ### 1. 새 프로파일 생성
83
+ ```bash
84
+ # 로컬호스트 격리 (공용 WiFi에서 토픽 충돌 방지)
85
+ uv run ros-dds-manager generate cyclonedds sim-local --localhost --domain-id 1 --activate
86
+
87
+ # 특정 유선 NIC 및 피어 지정 (Fast-DDS 멀티캐스트 비활성화)
88
+ uv run ros-dds-manager generate fastdds robot-eth --interface eth0 --no-multicast --peers 192.168.1.10,192.168.1.11
89
+
90
+ # 생성 미리보기 (Dry Run)
91
+ uv run ros-dds-manager generate cyclonedds preview-test --localhost --dry-run
92
+
93
+ # 대화형 마법사 실행 (TTY 전용)
94
+ uv run ros-dds-manager init
95
+ ```
96
+
97
+ ### 3. 프로파일 목록 및 상세 조회
98
+ ```bash
99
+ uv run ros-dds-manager list
100
+ uv run ros-dds-manager list --json
101
+ uv run ros-dds-manager show sim-local
102
+ ```
103
+
104
+ ### 4. 프로파일 전환 (Switch)
105
+ ```bash
106
+ # 활성 프로파일 교체
107
+ uv run ros-dds-manager switch sim-local
108
+ # 또는 별칭 사용
109
+ uv run ros-dds-manager use sim-local
110
+ ```
111
+
112
+ ### 5. 쉘 환경변수 연동 방법 (3가지 방식 지원)
113
+ CLI 도구(자식 프로세스)는 부모 쉘의 환경변수를 직접 바꿀 수 없으므로, 편의에 맞게 세 가지 방식 중 하나를 사용할 수 있습니다:
114
+
115
+ 1. **`~/.bashrc` 영구 연동 (가장 추천)**:
116
+ ```bash
117
+ echo 'source ~/.config/ros-dds-manager/current.sh' >> ~/.bashrc
118
+ ```
119
+ `switch` 명령어로 활성 프로파일을 바꾸면 `current.sh`가 즉시 갱신되므로, 새 터미널마다 자동으로 선택된 DDS 환경이 적용됩니다.
120
+
121
+ 2. **현재 쉘 즉시 적용 (one-shot)**:
122
+ ```bash
123
+ eval "$(ros-dds-manager env)"
124
+ # 또는
125
+ source ~/.config/ros-dds-manager/current.sh
126
+ ```
127
+
128
+ 3. **명령어 격리 실행 (`run`)**:
129
+ 현재 쉘 환경변수를 일체 건드리지 않고, 해당 프로파일이 적용된 서브프로세스로 실행합니다:
130
+ ```bash
131
+ ros-dds-manager run sim-local -- ros2 topic list
132
+ ```
133
+
134
+ ---
135
+
136
+ ## 📋 주요 명령어 (Commands)
137
+
138
+ | 명령어 | 설명 | 예시 |
139
+ | :--- | :--- | :--- |
140
+ | `list` | 저장된 모든 DDS 프로파일 목록 및 활성 상태 표시 (`--json`, `--plain`) | `ros-dds-manager list --json` |
141
+ | `show [name]` | 프로파일 상세 정보, 생성된 XML, 환경변수 출력 (`--json`) | `ros-dds-manager show sim-local` |
142
+ | `switch <name>` | 활성 프로파일 변경 및 `current.sh` 갱신 | `ros-dds-manager switch robot-eth` |
143
+ | `env [name]` | 쉘 `export` 구문 출력 (`--unset` 지원) | `eval "$(ros-dds-manager env)"` |
144
+ | `generate` | 플래그 기반으로 XML 및 프로파일 생성 (`--dry-run`, `--overwrite`) | `ros-dds-manager generate cyclonedds my-prof --localhost` |
145
+ | `init [name]` | 대화형 마법사 질문-답변으로 프로파일 생성 (TTY 전용) | `ros-dds-manager init` |
146
+ | `delete <name>`| 프로파일 삭제 (`--yes` 지원) | `ros-dds-manager delete old-profile --yes` |
147
+ | `run <name> -- <cmd>` | 특정 프로파일 환경을 주입하여 명령 실행 | `ros-dds-manager run sim-local -- ros2 launch ...` |
148
+ | `doctor` | ROS 2 환경변수, 활성 XML, 네트워크 상태 진단 (`--json`) | `ros-dds-manager doctor` |
149
+ | `config` | 앱 설정(`config.toml`) 관리 (`init`, `show`, `path`, `set`, `get`) | `ros-dds-manager config show` |
150
+
151
+ ---
152
+
153
+ ## 🛡️ CLI 표준 준수 ([clig.dev](https://clig.dev/))
154
+
155
+ ### 1. 표준 종료 코드 (Exit Codes)
156
+ | 코드 | 의미 | 설명 |
157
+ | :--- | :--- | :--- |
158
+ | `0` | `EXIT_SUCCESS` | 명령어가 성공적으로 완료됨 |
159
+ | `1` | `EXIT_ERROR` | 일반 런타임/운영 오류 (프로파일 없음 등) |
160
+ | `2` | `EXIT_USAGE` | 잘못된 플래그/인수 또는 비대화형 환경에서 필수 입력/확인(`--yes`) 누락 |
161
+ | `127`| `EXIT_NOT_FOUND` | `run` 명령에서 대상 실행 파일을 찾을 수 없음 |
162
+ | `130`| `EXIT_INTERRUPT` | 사용자가 Ctrl+C(SIGINT)로 인터럽트함 |
163
+
164
+ ### 2. 표준 플래그
165
+ - `--json` / `-j`: 기계 판독이 용이한 JSON 형태로 출력 (CI/CD 및 파이프라인 연동)
166
+ - `--no-input`: 프롬프트 대기 없이 즉시 실패 (CI/에이전트 안전 장치)
167
+ - `-q`, `--quiet`: 팁과 상태 배너 출력을 억제하여 순수 결과만 표기
168
+ - `-y`, `--yes`: 파괴적 작업(`delete`) 시 확인 절차 스킵
169
+ - `--dry-run`: 실제 디스크 저장 없이 생성될 XML과 환경변수 미리보기
170
+
171
+ ### 3. XDG Base Directory 규격 준수
172
+ 설정 파일 및 프로파일 저장소는 다음 우선순위에 따라 결정됩니다:
173
+ 1. `ROS_DDS_MANAGER_DIR` (사용자 지정 환경변수)
174
+ 2. `$XDG_CONFIG_HOME/ros-dds-manager` (지정된 경우)
175
+ 3. `~/.config/ros-dds-manager` (기본값)
176
+
177
+ ---
178
+
179
+ ## ⚙️ 설정 관리 (`config` 서브 커맨드)
180
+
181
+ `ros-dds-manager` 자체 동작 설정(`config.toml`)을 관리합니다:
182
+
183
+ - `ros-dds-manager config path`: 설정 파일 경로 및 존재 여부 확인 (`--local` 지원)
184
+ - `ros-dds-manager config show`: 현재 적용된 설정 내용 확인 (`--json` 지원)
185
+ - `ros-dds-manager config init`: 기본 `config.toml` 초기화 (`--overwrite`, `--local` 지원)
186
+ - `ros-dds-manager config set <key> <value>`: 설정값 변경 (예: `ros-dds-manager config set app.default_vendor fastdds`)
187
+ - `ros-dds-manager config get <key>`: 특정 키값 조회 (예: `ros-dds-manager config get app.default_vendor`)
188
+
189
+ ---
190
+
191
+ ## 💡 주요 시나리오별 설정 예제
192
+
193
+ ### 시나리오 1: 연구실/카페 공용 WiFi에서 시뮬레이션 혼선 방지 (Localhost 전용)
194
+ ```bash
195
+ ros-dds-manager generate cyclonedds local-gazebo \
196
+ --localhost \
197
+ --domain-id 1 \
198
+ --activate
199
+ ```
200
+
201
+ ### 시나리오 2: 로봇 내부의 특정 이더넷 카드(`enp4s0`)로 통신 고정
202
+ ```bash
203
+ ros-dds-manager generate cyclonedds robot-wired \
204
+ --interface enp4s0 \
205
+ --domain-id 42 \
206
+ --buffer-mb 20 \
207
+ --activate
208
+ ```
209
+
210
+ ### 시나리오 3: 멀티캐스트가 차단된 망에서 Fast-DDS 유니캐스트 피어 연결
211
+ ```bash
212
+ ros-dds-manager generate fastdds office-unicast \
213
+ --no-multicast \
214
+ --peers 192.168.10.20,192.168.10.21 \
215
+ --activate
216
+ ```
217
+
218
+ ### 시나리오 4: Fast-DDS Discovery Server 연결 (대규모 분산 로봇)
219
+ ```bash
220
+ ros-dds-manager generate fastdds ds-client \
221
+ --discovery-server client \
222
+ --server-ip 192.168.1.100 \
223
+ --server-port 11811 \
224
+ --activate
225
+ ```
226
+
227
+ ---
228
+
229
+ ## 🛠️ 개발 및 기여
230
+ - 에이전트 개발 지침: [AGENTS.md](file:///home/wkqco/Workspace/utils/ros-dds-manager/AGENTS.md)
231
+ - 변경 이력: [CHANGELOG.md](file:///home/wkqco/Workspace/utils/ros-dds-manager/CHANGELOG.md)
232
+ - 기여 가이드: [CONTRIBUTING.md](file:///home/wkqco/Workspace/utils/ros-dds-manager/CONTRIBUTING.md)
233
+ - 보안 정책: [SECURITY.md](file:///home/wkqco/Workspace/utils/ros-dds-manager/SECURITY.md)
234
+ - 라이선스: [LICENSE](file:///home/wkqco/Workspace/utils/ros-dds-manager/LICENSE) (Apache-2.0)