domd 2.1.30__tar.gz → 2.2.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 (110) hide show
  1. {domd-2.1.30 → domd-2.2.2}/PKG-INFO +1 -1
  2. {domd-2.1.30 → domd-2.2.2}/pyproject.toml +1 -1
  3. {domd-2.1.30 → domd-2.2.2}/src/domd/core/project_detection/command_handling.py +1 -1
  4. {domd-2.1.30 → domd-2.2.2}/src/domd/core/project_detection/detector.py +68 -30
  5. {domd-2.1.30 → domd-2.2.2}/LICENSE +0 -0
  6. {domd-2.1.30 → domd-2.2.2}/README.md +0 -0
  7. {domd-2.1.30 → domd-2.2.2}/src/domd/__init__.py +0 -0
  8. {domd-2.1.30 → domd-2.2.2}/src/domd/adapters/__init__.py +0 -0
  9. {domd-2.1.30 → domd-2.2.2}/src/domd/adapters/api/__init__.py +0 -0
  10. {domd-2.1.30 → domd-2.2.2}/src/domd/adapters/api/flask_api.py +0 -0
  11. {domd-2.1.30 → domd-2.2.2}/src/domd/adapters/cli/__init__.py +0 -0
  12. {domd-2.1.30 → domd-2.2.2}/src/domd/adapters/cli/command_presenter.py +0 -0
  13. {domd-2.1.30 → domd-2.2.2}/src/domd/adapters/formatters/__init__.py +0 -0
  14. {domd-2.1.30 → domd-2.2.2}/src/domd/adapters/formatters/markdown_formatter.py +0 -0
  15. {domd-2.1.30 → domd-2.2.2}/src/domd/adapters/persistence/__init__.py +0 -0
  16. {domd-2.1.30 → domd-2.2.2}/src/domd/adapters/persistence/in_memory_command_repository.py +0 -0
  17. {domd-2.1.30 → domd-2.2.2}/src/domd/adapters/persistence/shell_command_executor.py +0 -0
  18. {domd-2.1.30 → domd-2.2.2}/src/domd/api.py +0 -0
  19. {domd-2.1.30 → domd-2.2.2}/src/domd/application/__init__.py +0 -0
  20. {domd-2.1.30 → domd-2.2.2}/src/domd/application/factory.py +0 -0
  21. {domd-2.1.30 → domd-2.2.2}/src/domd/cli.py +0 -0
  22. {domd-2.1.30 → domd-2.2.2}/src/domd/command_execution/__init__.py +0 -0
  23. {domd-2.1.30 → domd-2.2.2}/src/domd/core/__init__.py +0 -0
  24. {domd-2.1.30 → domd-2.2.2}/src/domd/core/command_execution/__init__.py +0 -0
  25. {domd-2.1.30 → domd-2.2.2}/src/domd/core/command_execution/command_executor.py +0 -0
  26. {domd-2.1.30 → domd-2.2.2}/src/domd/core/command_execution/command_recorder.py +0 -0
  27. {domd-2.1.30 → domd-2.2.2}/src/domd/core/command_execution/command_runner.py +0 -0
  28. {domd-2.1.30 → domd-2.2.2}/src/domd/core/command_execution/environment_detector.py +0 -0
  29. {domd-2.1.30 → domd-2.2.2}/src/domd/core/command_execution/executor.py +0 -0
  30. {domd-2.1.30 → domd-2.2.2}/src/domd/core/commands/__init__.py +0 -0
  31. {domd-2.1.30 → domd-2.2.2}/src/domd/core/commands/command.py +0 -0
  32. {domd-2.1.30 → domd-2.2.2}/src/domd/core/commands/executor.py +0 -0
  33. {domd-2.1.30 → domd-2.2.2}/src/domd/core/detector.py +0 -0
  34. {domd-2.1.30 → domd-2.2.2}/src/domd/core/domain/__init__.py +0 -0
  35. {domd-2.1.30 → domd-2.2.2}/src/domd/core/domain/command.py +0 -0
  36. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/__init__.py +0 -0
  37. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/ansible_galaxy.py +0 -0
  38. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/ansible_inventory.py +0 -0
  39. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/ansible_playbook.py +0 -0
  40. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/ansible_role.py +0 -0
  41. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/ansible_vault.py +0 -0
  42. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/base.py +0 -0
  43. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/cargo_toml.py +0 -0
  44. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/composer_json.py +0 -0
  45. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/go_mod.py +0 -0
  46. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/makefile.py +0 -0
  47. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/package_json.py +0 -0
  48. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/pyproject_toml.py +0 -0
  49. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsers/tox_ini.py +0 -0
  50. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsing/__init__.py +0 -0
  51. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsing/base.py +0 -0
  52. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsing/file_processor.py +0 -0
  53. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsing/parser_registry.py +0 -0
  54. {domd-2.1.30 → domd-2.2.2}/src/domd/core/parsing/pattern_matcher.py +0 -0
  55. {domd-2.1.30 → domd-2.2.2}/src/domd/core/ports/__init__.py +0 -0
  56. {domd-2.1.30 → domd-2.2.2}/src/domd/core/ports/command_executor.py +0 -0
  57. {domd-2.1.30 → domd-2.2.2}/src/domd/core/ports/command_repository.py +0 -0
  58. {domd-2.1.30 → domd-2.2.2}/src/domd/core/ports/report_formatter.py +0 -0
  59. {domd-2.1.30 → domd-2.2.2}/src/domd/core/project_detection/__init__.py +0 -0
  60. {domd-2.1.30 → domd-2.2.2}/src/domd/core/project_detection/config_files.py +0 -0
  61. {domd-2.1.30 → domd-2.2.2}/src/domd/core/project_detection/virtualenv.py +0 -0
  62. {domd-2.1.30 → domd-2.2.2}/src/domd/core/reporters/__init__.py +0 -0
  63. {domd-2.1.30 → domd-2.2.2}/src/domd/core/reporters/base.py +0 -0
  64. {domd-2.1.30 → domd-2.2.2}/src/domd/core/reporters/done_md.py +0 -0
  65. {domd-2.1.30 → domd-2.2.2}/src/domd/core/reporters/todo_md.py +0 -0
  66. {domd-2.1.30 → domd-2.2.2}/src/domd/core/reporting/__init__.py +0 -0
  67. {domd-2.1.30 → domd-2.2.2}/src/domd/core/reporting/formatters.py +0 -0
  68. {domd-2.1.30 → domd-2.2.2}/src/domd/core/reporting/reporter.py +0 -0
  69. {domd-2.1.30 → domd-2.2.2}/src/domd/core/services/__init__.py +0 -0
  70. {domd-2.1.30 → domd-2.2.2}/src/domd/core/services/command_service.py +0 -0
  71. {domd-2.1.30 → domd-2.2.2}/src/domd/core/services/report_service.py +0 -0
  72. {domd-2.1.30 → domd-2.2.2}/src/domd/core/utils/__init__.py +0 -0
  73. {domd-2.1.30 → domd-2.2.2}/src/domd/core/utils/command_utils.py +0 -0
  74. {domd-2.1.30 → domd-2.2.2}/src/domd/core/utils/environment.py +0 -0
  75. {domd-2.1.30 → domd-2.2.2}/src/domd/core/utils/file_utils.py +0 -0
  76. {domd-2.1.30 → domd-2.2.2}/src/domd/core/utils/logging_utils.py +0 -0
  77. {domd-2.1.30 → domd-2.2.2}/src/domd/core/utils/virtualenv.py +0 -0
  78. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/__init__.py +0 -0
  79. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/ansible.py +0 -0
  80. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/base.py +0 -0
  81. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/build_systems.py +0 -0
  82. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/ci_cd.py +0 -0
  83. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/docker/__init__.py +0 -0
  84. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/docker/docker_compose.py +0 -0
  85. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/docker/dockerfile.py +0 -0
  86. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/docker.py +0 -0
  87. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/javascript/__init__.py +0 -0
  88. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/javascript.py +0 -0
  89. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/package_json.py +0 -0
  90. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/python.py +0 -0
  91. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/test_build_systems.py +0 -0
  92. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/test_ci_cd.py +0 -0
  93. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/test_docker.py +0 -0
  94. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/test_javascript.py +0 -0
  95. {domd-2.1.30 → domd-2.2.2}/src/domd/parsers/test_python.py +0 -0
  96. {domd-2.1.30 → domd-2.2.2}/src/domd/parsing/__init__.py +0 -0
  97. {domd-2.1.30 → domd-2.2.2}/src/domd/parsing/base.py +0 -0
  98. {domd-2.1.30 → domd-2.2.2}/src/domd/reporters/__init__.py +0 -0
  99. {domd-2.1.30 → domd-2.2.2}/src/domd/reporters/console.py +0 -0
  100. {domd-2.1.30 → domd-2.2.2}/src/domd/reporters/json_reporter.py +0 -0
  101. {domd-2.1.30 → domd-2.2.2}/src/domd/reporters/test_console.py +0 -0
  102. {domd-2.1.30 → domd-2.2.2}/src/domd/reporters/test_json_reporter.py +0 -0
  103. {domd-2.1.30 → domd-2.2.2}/src/domd/reporters/test_todo_md.py +0 -0
  104. {domd-2.1.30 → domd-2.2.2}/src/domd/reporters/todo_md.py +0 -0
  105. {domd-2.1.30 → domd-2.2.2}/src/domd/reporting/__init__.py +0 -0
  106. {domd-2.1.30 → domd-2.2.2}/src/domd/utils/__init__.py +0 -0
  107. {domd-2.1.30 → domd-2.2.2}/src/domd/utils/command_runner.py +0 -0
  108. {domd-2.1.30 → domd-2.2.2}/src/domd/utils/file_utils.py +0 -0
  109. {domd-2.1.30 → domd-2.2.2}/src/domd/utils/test_command_runner.py +0 -0
  110. {domd-2.1.30 → domd-2.2.2}/src/domd/utils/test_file_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: domd
3
- Version: 2.1.30
3
+ Version: 2.2.2
4
4
  Summary: Project Command Detector - Automatically detects and tests project commands, generates TODO.md for failed commands
5
5
  License: Apache-2.0
6
6
  Author: Tom Sapletta
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "domd"
3
- version = "2.1.30"
3
+ version = "2.2.2"
4
4
  description = "Project Command Detector - Automatically detects and tests project commands, generates TODO.md for failed commands"
5
5
  authors = ["Tom Sapletta <info@softreck.dev>"]
6
6
  maintainers = ["WRONAI Team"]
@@ -115,7 +115,7 @@ class CommandHandler:
115
115
 
116
116
  # Log the result
117
117
  if result.success:
118
- logger.info(f"Command succeeded in {result.execution_time:.2f}s")
118
+ logger.info(f"Command succeeded in {result.execution_time:.2f} s")
119
119
  self.successful_commands.append(result_dict)
120
120
  else:
121
121
  logger.error(f"Command failed with code {result.return_code}")
@@ -213,6 +213,47 @@ class ProjectCommandDetector:
213
213
  """
214
214
  return get_virtualenv_environment(self.venv_info)
215
215
 
216
+ def _process_directory_readme(
217
+ self, directory: Path, all_commands: list, parent_dir: str = None
218
+ ) -> None:
219
+ """Process a README.md file in a directory and update command metadata.
220
+
221
+ Args:
222
+ directory: Directory containing the README.md
223
+ all_commands: List to append found commands to
224
+ parent_dir: Name of parent directory (for second-level directories)
225
+ """
226
+ readme_path = directory / "README.md"
227
+ if not readme_path.exists() or not readme_path.is_file():
228
+ return
229
+
230
+ # Determine display path for logging and source
231
+ if parent_dir:
232
+ display_path = f"{parent_dir}/{directory.name}/README.md"
233
+ else:
234
+ display_path = f"{directory.name}/README.md"
235
+
236
+ logger.info(f"Found README.md: {display_path}")
237
+
238
+ # Process README.md in directory
239
+ commands = self._process_file_commands(readme_path)
240
+
241
+ # Update command metadata with directory context
242
+ for cmd in commands:
243
+ if isinstance(cmd, dict):
244
+ cmd_metadata = cmd.setdefault("metadata", {})
245
+ cmd_metadata["cwd"] = str(directory)
246
+ cmd_metadata["source"] = display_path
247
+ elif hasattr(cmd, "metadata"):
248
+ if not hasattr(cmd.metadata, "get") or not callable(cmd.metadata.get):
249
+ cmd.metadata = {"original_metadata": cmd.metadata}
250
+ cmd.metadata["cwd"] = str(directory)
251
+ if not getattr(cmd, "source", None):
252
+ cmd.source = display_path
253
+
254
+ all_commands.extend(commands)
255
+ logger.info(f"Found {len(commands)} commands in {display_path}")
256
+
216
257
  def _process_file_commands(self, file_path: Path) -> List[Dict]:
217
258
  """Process a single file and extract commands.
218
259
 
@@ -309,37 +350,32 @@ class ProjectCommandDetector:
309
350
  for file_path in config_files:
310
351
  all_commands.extend(self._process_file_commands(file_path))
311
352
 
312
- # 2. Scan first-level subdirectories for README.md files
353
+ # 2. Scan first and second level subdirectories for README.md files
313
354
  try:
314
- for item in self.project_path.iterdir():
315
- if item.is_dir() and not item.name.startswith("."):
316
- readme_path = item / "README.md"
317
- if readme_path.exists() and readme_path.is_file():
318
- logger.info(f"Found README.md in subdirectory: {item.name}")
319
- # Process README.md in subdirectory
320
- commands = self._process_file_commands(readme_path)
321
-
322
- # Update command metadata with subdirectory context
323
- for cmd in commands:
324
- if isinstance(cmd, dict):
325
- cmd_metadata = cmd.setdefault("metadata", {})
326
- cmd_metadata["cwd"] = str(item)
327
- cmd_metadata["source"] = f"{item.name}/README.md"
328
- elif hasattr(cmd, "metadata"):
329
- if not hasattr(cmd.metadata, "get") or not callable(
330
- cmd.metadata.get
331
- ):
332
- cmd.metadata = {"original_metadata": cmd.metadata}
333
- cmd.metadata["cwd"] = str(item)
334
- if not getattr(cmd, "source", None):
335
- cmd.source = f"{item.name}/README.md"
336
-
337
- all_commands.extend(commands)
338
- logger.info(
339
- f"Found {len(commands)} commands in {item.name}/README.md"
355
+ # First level directories
356
+ for level1_item in self.project_path.iterdir():
357
+ if not level1_item.is_dir() or level1_item.name.startswith("."):
358
+ continue
359
+
360
+ # Process level 1 README
361
+ self._process_directory_readme(level1_item, all_commands)
362
+
363
+ # Scan second level
364
+ try:
365
+ for level2_item in level1_item.iterdir():
366
+ if not level2_item.is_dir() or level2_item.name.startswith("."):
367
+ continue
368
+
369
+ # Process level 2 README
370
+ self._process_directory_readme(
371
+ level2_item, all_commands, level1_item.name
340
372
  )
373
+ except Exception as e:
374
+ logger.error(
375
+ f"Error scanning subdirectory {level1_item}: {e}", exc_info=True
376
+ )
341
377
  except Exception as e:
342
- logger.error(f"Error scanning subdirectories: {e}", exc_info=True)
378
+ logger.error(f"Error scanning directories: {e}", exc_info=True)
343
379
 
344
380
  logger.info(f"Found {len(all_commands)} commands in total")
345
381
 
@@ -654,7 +690,9 @@ class ProjectCommandDetector:
654
690
  source = cmd_dict.get("source", "Unknown")
655
691
 
656
692
  f.write(f"### 🔧 Fix: {command}\n") # noqa: E231
657
- f.write(f"- [ ] **Command**: `{command}` \n") # noqa: E231
693
+ f.write(
694
+ f"- [ ] **Command**: `{command}` \n"
695
+ ) # noqa: E201,E231
658
696
  f.write(f"- **Error**: {error} \n") # noqa: E231
659
697
  f.write(f"- **Source**: `{source}`\n") # noqa: E231
660
698
  f.write("- **Fix Suggestion**: \n\n") # noqa: E231
@@ -680,7 +718,7 @@ class ProjectCommandDetector:
680
718
  source = cmd_dict.get("source", "Unknown")
681
719
 
682
720
  f.write(f"- [x] `{command}` \n") # noqa: E231
683
- f.write(f" - Source: `{source}`\n") # noqa: E231
721
+ f.write(f" - Source: `{source}`\n") # noqa: E221,E231
684
722
  else:
685
723
  f.write("No commands were executed successfully.\n")
686
724
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes