domd 2.2.67__tar.gz → 2.3.3__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.
- {domd-2.2.67 → domd-2.3.3}/PKG-INFO +50 -42
- {domd-2.2.67 → domd-2.3.3}/README.md +13 -2
- {domd-2.2.67 → domd-2.3.3}/pyproject.toml +98 -8
- domd-2.3.3/setup.cfg +4 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/__init__.py +1 -1
- domd-2.3.3/src/domd/cli/__init__.py +19 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/cli/cli.py +6 -8
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/handlers/command_handler.py +1 -1
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_execution/executor.py +9 -2
- domd-2.3.3/src/domd/core/project_detection/file_command_processor.py +122 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/utils/environment.py +15 -2
- domd-2.3.3/src/domd.egg-info/PKG-INFO +849 -0
- domd-2.3.3/src/domd.egg-info/SOURCES.txt +147 -0
- domd-2.3.3/src/domd.egg-info/dependency_links.txt +1 -0
- domd-2.3.3/src/domd.egg-info/entry_points.txt +5 -0
- domd-2.3.3/src/domd.egg-info/requires.txt +29 -0
- domd-2.3.3/src/domd.egg-info/top_level.txt +1 -0
- domd-2.3.3/tests/test_ansible.py +179 -0
- domd-2.3.3/tests/test_ansible_galaxy.py +173 -0
- domd-2.3.3/tests/test_ansible_inventory.py +113 -0
- domd-2.3.3/tests/test_ansible_playbook.py +124 -0
- domd-2.3.3/tests/test_ansible_roles.py +134 -0
- domd-2.3.3/tests/test_ansible_vault.py +111 -0
- domd-2.3.3/tests/test_cli.py +4 -0
- domd-2.3.3/tests/test_command_handling.py +245 -0
- domd-2.3.3/tests/test_command_testing.py +201 -0
- domd-2.3.3/tests/test_detector.py +1377 -0
- domd-2.3.3/tests/test_detector_poetry_scripts.py +88 -0
- domd-2.3.3/tests/test_virtualenv.py +277 -0
- domd-2.2.67/CHANGELOG.md +0 -243
- domd-2.2.67/VERSION +0 -1
- domd-2.2.67/src/domd/cli/__init__.py +0 -9
- {domd-2.2.67 → domd-2.3.3}/LICENSE +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/adapters/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/adapters/api/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/adapters/api/command_testing.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/adapters/api/flask_api.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/adapters/cli/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/adapters/cli/command_presenter.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/adapters/formatters/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/adapters/formatters/markdown_formatter.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/adapters/persistence/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/adapters/persistence/in_memory_command_repository.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/adapters/persistence/shell_command_executor.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/api.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/application/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/application/factory.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/cli/commands/test_commands.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/command_execution/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/base_detector.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/docker_tester.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/handlers/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/handlers/config_handler.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/models.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/parsers/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/parsers/base_parser.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/parsers/parser_registry.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/project_detector.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/utils/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/utils/file_utils.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_detection/utils/virtualenv.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_execution/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_execution/command_executor.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_execution/command_recorder.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_execution/command_runner.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/command_execution/environment_detector.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/commands/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/commands/command.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/commands/executor.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/detector.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/domain/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/domain/command.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/ansible_galaxy.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/ansible_inventory.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/ansible_playbook.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/ansible_role.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/ansible_vault.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/base.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/cargo_toml.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/composer_json.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/go_mod.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/makefile.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/package_json.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/pyproject_toml.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsers/tox_ini.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsing/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsing/base.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsing/file_processor.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsing/parser_registry.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/parsing/pattern_matcher.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/ports/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/ports/command_executor.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/ports/command_repository.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/ports/report_formatter.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/project_detection/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/project_detection/command_handling.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/project_detection/config_files.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/project_detection/detector.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/project_detection/virtualenv.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/reporters/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/reporters/base.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/reporters/done_md.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/reporters/todo_md.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/reporting/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/reporting/formatters.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/reporting/reporter.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/services/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/services/command_service.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/services/report_service.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/utils/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/utils/command_utils.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/utils/file_utils.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/utils/logging_utils.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/core/utils/virtualenv.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/ansible.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/base.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/build_systems.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/ci_cd.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/docker/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/docker/docker_compose.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/docker/dockerfile.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/docker.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/javascript/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/javascript.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/markdown_parser.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/package_json.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/python.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/test_build_systems.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/test_ci_cd.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/test_docker.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/test_javascript.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsers/test_python.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsing/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/parsing/base.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/reporters/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/reporters/console.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/reporters/json_reporter.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/reporters/test_console.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/reporters/test_json_reporter.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/reporters/test_todo_md.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/reporters/todo_md.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/reporting/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/utils/__init__.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/utils/command_runner.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/utils/file_utils.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/utils/path_utils.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/utils/test_command_runner.py +0 -0
- {domd-2.2.67 → domd-2.3.3}/src/domd/utils/test_file_utils.py +0 -0
|
@@ -1,51 +1,61 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: domd
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.3
|
|
4
4
|
Summary: ✓ DoMD - Do Markdown Docs - automatically detect, run and show working commands in DONE.md and errors in TODO.md markdown files
|
|
5
|
-
|
|
6
|
-
Author: Tom Sapletta
|
|
7
|
-
Author-email: info@softreck.dev
|
|
5
|
+
Author-email: Tom Sapletta <info@softreck.dev>, Tom Sapletta <tom@sapletta.com>
|
|
8
6
|
Maintainer: WRONAI Team
|
|
9
|
-
|
|
10
|
-
Classifier: Development Status :: 3 - Alpha
|
|
11
|
-
Classifier: Environment :: Console
|
|
12
|
-
Classifier: Intended Audience :: Developers
|
|
13
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
-
Classifier: Natural Language :: English
|
|
15
|
-
Classifier: Operating System :: OS Independent
|
|
16
|
-
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
24
|
-
Classifier: Topic :: Software Development :: Build Tools
|
|
25
|
-
Classifier: Topic :: Software Development :: Quality Assurance
|
|
26
|
-
Classifier: Topic :: Software Development :: Testing
|
|
27
|
-
Classifier: Topic :: System :: Systems Administration
|
|
28
|
-
Provides-Extra: all
|
|
29
|
-
Provides-Extra: api
|
|
30
|
-
Provides-Extra: cli
|
|
31
|
-
Provides-Extra: ui
|
|
32
|
-
Requires-Dist: click (>=8.1.0,<9.0.0) ; extra == "cli" or extra == "all"
|
|
33
|
-
Requires-Dist: colorama (>=0.4.6,<0.5.0) ; extra == "ui" or extra == "all"
|
|
34
|
-
Requires-Dist: docker (>=6.1.3,<7.0.0)
|
|
35
|
-
Requires-Dist: flask (>=2.0.0,<3.0.0) ; extra == "api" or extra == "all"
|
|
36
|
-
Requires-Dist: flask-cors (>=6.0.1,<7.0.0)
|
|
37
|
-
Requires-Dist: pyyaml (>=6.0,<7.0)
|
|
38
|
-
Requires-Dist: rich (>=13.0.0,<14.0.0) ; extra == "ui" or extra == "all"
|
|
39
|
-
Requires-Dist: toml (>=0.10.2,<0.11.0)
|
|
40
|
-
Project-URL: Bug Tracker, https://github.com/wronai/domd/issues
|
|
41
|
-
Project-URL: Changelog, https://github.com/wronai/domd/blob/main/CHANGELOG.md
|
|
42
|
-
Project-URL: Documentation, https://wronai.github.io/domd
|
|
7
|
+
License: Apache-2.0
|
|
43
8
|
Project-URL: Homepage, https://github.com/wronai/domd
|
|
9
|
+
Project-URL: Documentation, https://domd.readthedocs.io
|
|
44
10
|
Project-URL: Repository, https://github.com/wronai/domd.git
|
|
11
|
+
Project-URL: Bug Tracker, https://github.com/wronai/domd/issues
|
|
12
|
+
Project-URL: Changelog, https://github.com/wronai/domd/blob/main/CHANGELOG.md
|
|
13
|
+
Requires-Python: <4.0,>=3.9
|
|
45
14
|
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: pyyaml>=6.0
|
|
17
|
+
Requires-Dist: toml>=0.10.2
|
|
18
|
+
Requires-Dist: docker>=6.1.3
|
|
19
|
+
Requires-Dist: flask-cors>=6.0.1
|
|
20
|
+
Requires-Dist: goal>=2.1.0
|
|
21
|
+
Requires-Dist: costs>=0.1.20
|
|
22
|
+
Requires-Dist: pfix>=0.1.60
|
|
23
|
+
Provides-Extra: dev
|
|
24
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
25
|
+
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest-mock>=3.10.0; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-docker>=2.0.0; extra == "dev"
|
|
28
|
+
Requires-Dist: black>=23.0.0; extra == "dev"
|
|
29
|
+
Requires-Dist: isort>=5.12.0; extra == "dev"
|
|
30
|
+
Requires-Dist: flake8>=6.0.0; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
32
|
+
Requires-Dist: pylint>=2.17.0; extra == "dev"
|
|
33
|
+
Requires-Dist: pre-commit>=3.0.0; extra == "dev"
|
|
34
|
+
Requires-Dist: coverage>=7.0.0; extra == "dev"
|
|
35
|
+
Requires-Dist: goal>=2.1.0; extra == "dev"
|
|
36
|
+
Requires-Dist: costs>=0.1.20; extra == "dev"
|
|
37
|
+
Requires-Dist: pfix>=0.1.60; extra == "dev"
|
|
38
|
+
Provides-Extra: all
|
|
39
|
+
Requires-Dist: colorama>=0.4.6; extra == "all"
|
|
40
|
+
Requires-Dist: rich>=13.0.0; extra == "all"
|
|
41
|
+
Requires-Dist: click>=8.1.0; extra == "all"
|
|
42
|
+
Requires-Dist: flask>=2.0.0; extra == "all"
|
|
43
|
+
Dynamic: license-file
|
|
46
44
|
|
|
47
45
|
# ✓ DoMD - Do Markdown Docs
|
|
48
46
|
|
|
47
|
+
## AI Cost Tracking
|
|
48
|
+
|
|
49
|
+
 
|
|
50
|
+
|
|
51
|
+
This project uses AI-generated code. Total cost: **$7.5000** with **100** AI commits.
|
|
52
|
+
|
|
53
|
+
Generated on 2026-04-08 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/models/openrouter/qwen/qwen3-coder-next)
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
49
59
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
50
60
|
[](https://www.python.org/downloads/)
|
|
51
61
|
[](https://github.com/psf/black)
|
|
@@ -331,8 +341,7 @@ Contributions are welcome! Please read our [Contributing Guide][contributing] fo
|
|
|
331
341
|
|
|
332
342
|
## License
|
|
333
343
|
|
|
334
|
-
|
|
335
|
-
|
|
344
|
+
Licensed under Apache-2.0.
|
|
336
345
|
## Need Help?
|
|
337
346
|
|
|
338
347
|
Open an [issue][issues] if you need help or have questions.
|
|
@@ -838,4 +847,3 @@ repos:
|
|
|
838
847
|
[docker-url]: https://www.docker.com/
|
|
839
848
|
[docs-badge]: https://img.shields.io/badge/Docs-Read%20the%20Docs-blue
|
|
840
849
|
[docs-url]: https://wronai.github.io/domd/
|
|
841
|
-
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# ✓ DoMD - Do Markdown Docs
|
|
2
2
|
|
|
3
|
+
## AI Cost Tracking
|
|
4
|
+
|
|
5
|
+
 
|
|
6
|
+
|
|
7
|
+
This project uses AI-generated code. Total cost: **$7.5000** with **100** AI commits.
|
|
8
|
+
|
|
9
|
+
Generated on 2026-04-08 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/models/openrouter/qwen/qwen3-coder-next)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
3
15
|
[](https://opensource.org/licenses/Apache-2.0)
|
|
4
16
|
[](https://www.python.org/downloads/)
|
|
5
17
|
[](https://github.com/psf/black)
|
|
@@ -285,8 +297,7 @@ Contributions are welcome! Please read our [Contributing Guide][contributing] fo
|
|
|
285
297
|
|
|
286
298
|
## License
|
|
287
299
|
|
|
288
|
-
|
|
289
|
-
|
|
300
|
+
Licensed under Apache-2.0.
|
|
290
301
|
## Need Help?
|
|
291
302
|
|
|
292
303
|
Open an [issue][issues] if you need help or have questions.
|
|
@@ -1,8 +1,72 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "domd"
|
|
3
|
+
version = "2.3.3"
|
|
4
|
+
description = " ✓ DoMD - Do Markdown Docs - automatically detect, run and show working commands in DONE.md and errors in TODO.md markdown files"
|
|
5
|
+
authors = [
|
|
6
|
+
{name = "Tom Sapletta", email = "info@softreck.dev"},
|
|
7
|
+
{name = "Tom Sapletta", email = "tom@sapletta.com"},
|
|
8
|
+
]
|
|
9
|
+
maintainers = [
|
|
10
|
+
{name = "WRONAI Team"},
|
|
11
|
+
]
|
|
12
|
+
license = {text = "Apache-2.0"}
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
requires-python = ">=3.9,<4.0"
|
|
15
|
+
dependencies = [
|
|
16
|
+
"pyyaml>=6.0",
|
|
17
|
+
"toml>=0.10.2",
|
|
18
|
+
"docker>=6.1.3",
|
|
19
|
+
"flask-cors>=6.0.1",
|
|
20
|
+
"goal>=2.1.0",
|
|
21
|
+
"costs>=0.1.20",
|
|
22
|
+
"pfix>=0.1.60",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.optional-dependencies]
|
|
26
|
+
dev = [
|
|
27
|
+
"pytest>=7.0.0",
|
|
28
|
+
"pytest-cov>=4.0.0",
|
|
29
|
+
"pytest-mock>=3.10.0",
|
|
30
|
+
"pytest-docker>=2.0.0",
|
|
31
|
+
"black>=23.0.0",
|
|
32
|
+
"isort>=5.12.0",
|
|
33
|
+
"flake8>=6.0.0",
|
|
34
|
+
"mypy>=1.0.0",
|
|
35
|
+
"pylint>=2.17.0",
|
|
36
|
+
"pre-commit>=3.0.0",
|
|
37
|
+
"coverage>=7.0.0",
|
|
38
|
+
"goal>=2.1.0",
|
|
39
|
+
"costs>=0.1.20",
|
|
40
|
+
"pfix>=0.1.60",
|
|
41
|
+
]
|
|
42
|
+
all = [
|
|
43
|
+
"colorama>=0.4.6",
|
|
44
|
+
"rich>=13.0.0",
|
|
45
|
+
"click>=8.1.0",
|
|
46
|
+
"flask>=2.0.0",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
[project.scripts]
|
|
50
|
+
domd = "domd.cli:main"
|
|
51
|
+
domd-api = "domd.api:main"
|
|
52
|
+
project-detector = "domd.cli:main"
|
|
53
|
+
cmd-detector = "domd.cli:main"
|
|
54
|
+
|
|
55
|
+
[project.urls]
|
|
56
|
+
Homepage = "https://github.com/wronai/domd"
|
|
57
|
+
Documentation = "https://domd.readthedocs.io"
|
|
58
|
+
Repository = "https://github.com/wronai/domd.git"
|
|
59
|
+
"Bug Tracker" = "https://github.com/wronai/domd/issues"
|
|
60
|
+
Changelog = "https://github.com/wronai/domd/blob/main/CHANGELOG.md"
|
|
61
|
+
|
|
1
62
|
[tool.poetry]
|
|
2
63
|
name = "domd"
|
|
3
|
-
version = "2.2
|
|
64
|
+
version = "2.3.2"
|
|
4
65
|
description = " ✓ DoMD - Do Markdown Docs - automatically detect, run and show working commands in DONE.md and errors in TODO.md markdown files"
|
|
5
|
-
authors = [
|
|
66
|
+
authors = [
|
|
67
|
+
{name = "Tom Sapletta", email = "info@softreck.dev"},
|
|
68
|
+
{name = "Tom Sapletta", email = "tom@sapletta.com"},
|
|
69
|
+
]
|
|
6
70
|
maintainers = ["WRONAI Team"]
|
|
7
71
|
license = "Apache-2.0"
|
|
8
72
|
readme = "README.md"
|
|
@@ -15,8 +79,7 @@ packages = [
|
|
|
15
79
|
include = [
|
|
16
80
|
"README.md",
|
|
17
81
|
"CHANGELOG.md",
|
|
18
|
-
"LICENSE"
|
|
19
|
-
"VERSION"
|
|
82
|
+
"LICENSE"
|
|
20
83
|
]
|
|
21
84
|
classifiers = [
|
|
22
85
|
"Development Status :: 3 - Alpha",
|
|
@@ -25,7 +88,6 @@ classifiers = [
|
|
|
25
88
|
"Topic :: Software Development :: Build Tools",
|
|
26
89
|
"Topic :: Software Development :: Testing",
|
|
27
90
|
"Topic :: System :: Systems Administration",
|
|
28
|
-
"License :: OSI Approved :: Apache Software License",
|
|
29
91
|
"Programming Language :: Python :: 3",
|
|
30
92
|
"Programming Language :: Python :: 3.8",
|
|
31
93
|
"Programming Language :: Python :: 3.9",
|
|
@@ -61,8 +123,8 @@ flask = { version = "^2.0.0", optional = true }
|
|
|
61
123
|
flask-cors = "^6.0.1"
|
|
62
124
|
|
|
63
125
|
[build-system]
|
|
64
|
-
requires = ["
|
|
65
|
-
build-backend = "
|
|
126
|
+
requires = ["setuptools>=42.0.0"]
|
|
127
|
+
build-backend = "setuptools.build_meta"
|
|
66
128
|
|
|
67
129
|
[tool.poetry.scripts]
|
|
68
130
|
domd = "domd.cli:main"
|
|
@@ -195,7 +257,6 @@ markers = [
|
|
|
195
257
|
"commands: marks tests for command detection",
|
|
196
258
|
"parsers: marks tests for file parsers",
|
|
197
259
|
]
|
|
198
|
-
pythonpath = ["src"]
|
|
199
260
|
|
|
200
261
|
[tool.coverage.run]
|
|
201
262
|
source = ["src/domd"]
|
|
@@ -278,3 +339,32 @@ path = "src/domd/__init__.py"
|
|
|
278
339
|
|
|
279
340
|
[tool.hatch.build.targets.wheel]
|
|
280
341
|
packages = ["src/domd"]
|
|
342
|
+
|
|
343
|
+
[tool.pfix]
|
|
344
|
+
# Self-healing Python configuration
|
|
345
|
+
model = "openrouter/qwen/qwen3-coder-next"
|
|
346
|
+
auto_apply = true
|
|
347
|
+
auto_install_deps = true
|
|
348
|
+
auto_restart = false
|
|
349
|
+
max_retries = 3
|
|
350
|
+
create_backups = false
|
|
351
|
+
git_auto_commit = false
|
|
352
|
+
|
|
353
|
+
[tool.pfix.runtime_todo]
|
|
354
|
+
enabled = true
|
|
355
|
+
todo_file = "TODO.md"
|
|
356
|
+
min_severity = "low"
|
|
357
|
+
deduplicate = true
|
|
358
|
+
|
|
359
|
+
[tool.costs]
|
|
360
|
+
# AI Cost tracking configuration
|
|
361
|
+
badge = true
|
|
362
|
+
update_readme = true
|
|
363
|
+
readme_path = "README.md"
|
|
364
|
+
default_model = "openrouter/qwen/qwen3-coder-next"
|
|
365
|
+
analysis_mode = "byok"
|
|
366
|
+
full_history = true
|
|
367
|
+
max_commits = 500
|
|
368
|
+
|
|
369
|
+
# Cost thresholds for badge colors (USD)
|
|
370
|
+
badge_color_thresholds = { low = 1.0, medium = 5.0, high = 10.0, critical = 50.0 }
|
domd-2.3.3/setup.cfg
ADDED
|
@@ -7,7 +7,7 @@ generates TODO.md for failed commands with detailed error reports.
|
|
|
7
7
|
Supports: Makefile, package.json, pyproject.toml, Docker, CI/CD workflows, and more.
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
__version__ = "2.
|
|
10
|
+
__version__ = "2.3.3"
|
|
11
11
|
__author__ = "Tom Sapletta"
|
|
12
12
|
__email__ = "info@softreck.dev"
|
|
13
13
|
__license__ = "Apache-2.0"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"""
|
|
2
|
+
DoMD CLI Module
|
|
3
|
+
|
|
4
|
+
This module provides the command-line interface for the DoMD tool.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from domd.application.factory import ApplicationFactory # noqa: F401
|
|
8
|
+
from domd.core.detector import ProjectCommandDetector # noqa: F401
|
|
9
|
+
|
|
10
|
+
from .cli import create_parser, main, start_web_interface, validate_args # noqa: F401
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"main",
|
|
14
|
+
"create_parser",
|
|
15
|
+
"validate_args",
|
|
16
|
+
"start_web_interface",
|
|
17
|
+
"ApplicationFactory",
|
|
18
|
+
"ProjectCommandDetector",
|
|
19
|
+
]
|
|
@@ -102,7 +102,8 @@ def start_web_interface(args: argparse.Namespace) -> int:
|
|
|
102
102
|
|
|
103
103
|
# Get the directory of this file
|
|
104
104
|
current_dir = Path(__file__).parent
|
|
105
|
-
|
|
105
|
+
# cli.py is in src/domd/cli/, so we need to go up 3 levels to reach project root
|
|
106
|
+
frontend_dir = current_dir.parent.parent.parent / "frontend"
|
|
106
107
|
|
|
107
108
|
if not frontend_dir.exists():
|
|
108
109
|
print(f"❌ Error: Frontend directory not found at {frontend_dir}")
|
|
@@ -404,7 +405,7 @@ def handle_generate_ignore(project_path: Path, ignore_file: str) -> int:
|
|
|
404
405
|
project_path=project_path,
|
|
405
406
|
ignore_file=ignore_file,
|
|
406
407
|
)
|
|
407
|
-
detector.
|
|
408
|
+
detector.generate_doignore_template()
|
|
408
409
|
print(f"✅ Generated {ignore_file} template file")
|
|
409
410
|
print(f"💡 Edit {ignore_file} to customize ignored commands")
|
|
410
411
|
return 0
|
|
@@ -502,13 +503,10 @@ def main() -> int:
|
|
|
502
503
|
if line and not line.startswith("#"):
|
|
503
504
|
ignore_patterns.append(line)
|
|
504
505
|
|
|
505
|
-
# Initialize services with default values
|
|
506
|
+
# Initialize services with default values
|
|
506
507
|
timeout = getattr(args, "timeout", 30) # Default to 30 seconds
|
|
507
|
-
_ = getattr(args, "todo_file", "TODO.md") # Used in other parts
|
|
508
|
-
_ = getattr(args, "script_file", "todo.sh") # Used in other parts
|
|
509
|
-
_ = getattr(args, "ignore_file", ".doignore") # Used in other parts
|
|
510
508
|
|
|
511
|
-
# Initialize command service
|
|
509
|
+
# Initialize command service
|
|
512
510
|
command_service = ApplicationFactory.create_command_service(
|
|
513
511
|
repository=repository,
|
|
514
512
|
executor=executor,
|
|
@@ -590,7 +588,7 @@ def main() -> int:
|
|
|
590
588
|
if hasattr(args, "init_only") and args.init_only:
|
|
591
589
|
# Also generate .doignore template if it doesn't exist
|
|
592
590
|
if not ignore_file_path.exists():
|
|
593
|
-
detector.
|
|
591
|
+
detector.generate_doignore_template()
|
|
594
592
|
|
|
595
593
|
if not getattr(args, "quiet", False):
|
|
596
594
|
presenter.print_init_only(
|
|
@@ -663,7 +663,7 @@ class CommandHandler:
|
|
|
663
663
|
if any(cmd_str == cmd for cmd in special_commands) or any(
|
|
664
664
|
cmd_str == f"failing-{i}" for i in range(10)
|
|
665
665
|
):
|
|
666
|
-
logger.debug("
|
|
666
|
+
logger.debug("Command matches")
|
|
667
667
|
return True, "Command matches"
|
|
668
668
|
|
|
669
669
|
# Check for common shell commands with arguments
|
|
@@ -128,7 +128,7 @@ class CommandExecutor:
|
|
|
128
128
|
"""
|
|
129
129
|
# Start with default volume mapping
|
|
130
130
|
cwd_str = str(cwd)
|
|
131
|
-
volumes = {cwd_str: "/app"} #
|
|
131
|
+
volumes = {cwd_str: {"bind": "/app", "mode": "rw"}} # Docker-py format
|
|
132
132
|
workdir = "/app"
|
|
133
133
|
|
|
134
134
|
# Apply docker config if available
|
|
@@ -138,7 +138,14 @@ class CommandExecutor:
|
|
|
138
138
|
|
|
139
139
|
# Update volumes if specified in config
|
|
140
140
|
if "volumes" in docker_config:
|
|
141
|
-
|
|
141
|
+
config_volumes = docker_config["volumes"]
|
|
142
|
+
for host_path, container_path in config_volumes.items():
|
|
143
|
+
if isinstance(container_path, str):
|
|
144
|
+
# Convert simplified format to docker-py format
|
|
145
|
+
volumes[host_path] = {"bind": container_path, "mode": "rw"}
|
|
146
|
+
else:
|
|
147
|
+
# Already in docker-py format
|
|
148
|
+
volumes[host_path] = container_path
|
|
142
149
|
|
|
143
150
|
# Update workdir if specified in config
|
|
144
151
|
workdir = docker_config.get("workdir", workdir)
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Dict, List, Union
|
|
6
|
+
|
|
7
|
+
if __name__ == "__main__":
|
|
8
|
+
logger = logging.getLogger(__name__)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class FileCommandProcessor:
|
|
12
|
+
"""Helper responsible for parsing a single file into command objects."""
|
|
13
|
+
|
|
14
|
+
def __init__(self, project_path: Union[str, Path], parser_provider):
|
|
15
|
+
self.project_path = Path(project_path)
|
|
16
|
+
self._parser_provider = parser_provider
|
|
17
|
+
|
|
18
|
+
def process_file_commands(self, file_path: Union[str, Path]) -> List[Dict]:
|
|
19
|
+
"""Process a single file and extract commands.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
file_path: Path to the file to process (can be str or Path)
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
List of command dictionaries with metadata
|
|
26
|
+
"""
|
|
27
|
+
path = Path(file_path) if isinstance(file_path, str) else file_path
|
|
28
|
+
logger.debug(f"Processing file: {path}")
|
|
29
|
+
commands = []
|
|
30
|
+
try:
|
|
31
|
+
if not path.exists():
|
|
32
|
+
logger.warning(f"File not found: {path}")
|
|
33
|
+
return commands
|
|
34
|
+
if not path.is_file():
|
|
35
|
+
logger.debug(f"Path is not a file: {path}")
|
|
36
|
+
return commands
|
|
37
|
+
parser = self._parser_provider(path)
|
|
38
|
+
if not parser:
|
|
39
|
+
logger.debug(f"No suitable parser found for file: {path}")
|
|
40
|
+
return commands
|
|
41
|
+
if hasattr(parser, "file_path"):
|
|
42
|
+
parser.file_path = path
|
|
43
|
+
if hasattr(parser, "project_root") and (
|
|
44
|
+
not hasattr(parser, "_project_root_set")
|
|
45
|
+
):
|
|
46
|
+
parser.project_root = self.project_path
|
|
47
|
+
parser._project_root_set = True
|
|
48
|
+
file_commands = []
|
|
49
|
+
try:
|
|
50
|
+
if hasattr(parser, "parse_file") and callable(parser.parse_file):
|
|
51
|
+
file_commands = parser.parse_file(path)
|
|
52
|
+
elif hasattr(parser, "parse") and callable(parser.parse):
|
|
53
|
+
try:
|
|
54
|
+
file_commands = parser.parse()
|
|
55
|
+
except (TypeError, AttributeError) as e:
|
|
56
|
+
logger.debug(
|
|
57
|
+
f"Parser.parse() failed, trying with file path: {e}"
|
|
58
|
+
)
|
|
59
|
+
try:
|
|
60
|
+
file_commands = parser.parse(path)
|
|
61
|
+
except (TypeError, AttributeError) as e:
|
|
62
|
+
logger.debug(
|
|
63
|
+
f"Parser.parse(path) failed, trying with file content: {e}"
|
|
64
|
+
)
|
|
65
|
+
try:
|
|
66
|
+
content = path.read_text(encoding="utf-8")
|
|
67
|
+
file_commands = parser.parse(content)
|
|
68
|
+
except Exception as e:
|
|
69
|
+
logger.error(
|
|
70
|
+
f"Error parsing {path} with content: {e}",
|
|
71
|
+
exc_info=logger.isEnabledFor(logging.DEBUG),
|
|
72
|
+
)
|
|
73
|
+
return []
|
|
74
|
+
if not isinstance(file_commands, list):
|
|
75
|
+
logger.warning(
|
|
76
|
+
f"Parser returned non-list result: {type(file_commands)}"
|
|
77
|
+
)
|
|
78
|
+
file_commands = []
|
|
79
|
+
processed_commands = []
|
|
80
|
+
for cmd in file_commands:
|
|
81
|
+
try:
|
|
82
|
+
if cmd is None:
|
|
83
|
+
continue
|
|
84
|
+
if isinstance(cmd, dict):
|
|
85
|
+
cmd.setdefault("file", str(path))
|
|
86
|
+
if "source" not in cmd:
|
|
87
|
+
try:
|
|
88
|
+
cmd["source"] = str(
|
|
89
|
+
path.relative_to(self.project_path)
|
|
90
|
+
)
|
|
91
|
+
except ValueError:
|
|
92
|
+
cmd["source"] = str(path)
|
|
93
|
+
processed_commands.append(cmd)
|
|
94
|
+
elif hasattr(cmd, "__dict__"):
|
|
95
|
+
if not hasattr(cmd, "file") or not cmd.file:
|
|
96
|
+
cmd.file = str(path)
|
|
97
|
+
if not hasattr(cmd, "source") or not cmd.source:
|
|
98
|
+
try:
|
|
99
|
+
cmd.source = str(
|
|
100
|
+
path.relative_to(self.project_path)
|
|
101
|
+
)
|
|
102
|
+
except ValueError:
|
|
103
|
+
cmd.source = str(path)
|
|
104
|
+
processed_commands.append(cmd)
|
|
105
|
+
except Exception as e:
|
|
106
|
+
logger.warning(
|
|
107
|
+
f"Error processing command from {path}: {e}",
|
|
108
|
+
exc_info=logger.isEnabledFor(logging.DEBUG),
|
|
109
|
+
)
|
|
110
|
+
commands.extend(processed_commands)
|
|
111
|
+
logger.debug(f"Found {len(processed_commands)} commands in {path}")
|
|
112
|
+
except Exception as e:
|
|
113
|
+
logger.error(
|
|
114
|
+
f"Error parsing {path}: {e}",
|
|
115
|
+
exc_info=logger.isEnabledFor(logging.DEBUG),
|
|
116
|
+
)
|
|
117
|
+
except Exception as e:
|
|
118
|
+
logger.error(
|
|
119
|
+
f"Unexpected error processing {path}: {e}",
|
|
120
|
+
exc_info=logger.isEnabledFor(logging.DEBUG),
|
|
121
|
+
)
|
|
122
|
+
return commands
|
|
@@ -69,7 +69,10 @@ class EnvironmentDetector:
|
|
|
69
69
|
# Check if command matches any pattern in .dodocker
|
|
70
70
|
for pattern, config in self._dodocker_config.items():
|
|
71
71
|
if pattern in command:
|
|
72
|
-
|
|
72
|
+
# Ensure config is a dictionary, not a string or other type
|
|
73
|
+
if isinstance(config, dict):
|
|
74
|
+
return config
|
|
75
|
+
return None
|
|
73
76
|
return None
|
|
74
77
|
|
|
75
78
|
def should_use_docker(self, command: str) -> bool:
|
|
@@ -168,7 +171,9 @@ class EnvironmentDetector:
|
|
|
168
171
|
|
|
169
172
|
# Wait for container to finish and get exit code
|
|
170
173
|
result = container.wait()
|
|
171
|
-
|
|
174
|
+
if isinstance(result, dict):
|
|
175
|
+
return result.get("StatusCode", 1)
|
|
176
|
+
return 1
|
|
172
177
|
|
|
173
178
|
except docker.errors.ContainerError as e:
|
|
174
179
|
print(f"Docker container failed: {e}")
|
|
@@ -176,6 +181,14 @@ class EnvironmentDetector:
|
|
|
176
181
|
except docker.errors.ImageNotFound:
|
|
177
182
|
print(f"Docker image not found: {image}")
|
|
178
183
|
return 1
|
|
184
|
+
except docker.errors.NotFound:
|
|
185
|
+
# Container was auto-removed before wait completed (remove=True)
|
|
186
|
+
return 0
|
|
187
|
+
except docker.errors.APIError as e:
|
|
188
|
+
# Handle API errors including 404 for already-removed containers
|
|
189
|
+
if "Not Found" in str(e) or "No such container" in str(e):
|
|
190
|
+
return 0
|
|
191
|
+
raise
|
|
179
192
|
except Exception as e:
|
|
180
193
|
print(f"Error running Docker container: {e}")
|
|
181
194
|
return 1
|