ara-cli 0.1.9.76__py3-none-any.whl → 0.1.9.78__py3-none-any.whl
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.
Potentially problematic release.
This version of ara-cli might be problematic. Click here for more details.
- ara_cli/__main__.py +11 -4
- ara_cli/ara_command_parser.py +300 -92
- ara_cli/artefact_autofix.py +167 -89
- ara_cli/artefact_models/artefact_load.py +11 -3
- ara_cli/artefact_models/task_artefact_model.py +31 -23
- ara_cli/artefact_reader.py +74 -50
- ara_cli/chat.py +68 -1
- ara_cli/version.py +1 -1
- ara_cli-0.1.9.78.dist-info/METADATA +208 -0
- {ara_cli-0.1.9.76.dist-info → ara_cli-0.1.9.78.dist-info}/RECORD +15 -15
- tests/test_artefact_autofix.py +88 -1
- tests/test_chat.py +169 -30
- ara_cli-0.1.9.76.dist-info/METADATA +0 -16
- {ara_cli-0.1.9.76.dist-info → ara_cli-0.1.9.78.dist-info}/WHEEL +0 -0
- {ara_cli-0.1.9.76.dist-info → ara_cli-0.1.9.78.dist-info}/entry_points.txt +0 -0
- {ara_cli-0.1.9.76.dist-info → ara_cli-0.1.9.78.dist-info}/top_level.txt +0 -0
ara_cli/chat.py
CHANGED
|
@@ -34,6 +34,8 @@ Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat
|
|
|
34
34
|
".jpg": "image/jpeg",
|
|
35
35
|
".jpeg": "image/jpeg",
|
|
36
36
|
}
|
|
37
|
+
|
|
38
|
+
DOCUMENT_TYPE_EXTENSIONS = [".docx", ".doc", ".odt", ".pdf"]
|
|
37
39
|
|
|
38
40
|
def __init__(
|
|
39
41
|
self,
|
|
@@ -371,9 +373,52 @@ Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat
|
|
|
371
373
|
with open(self.chat_name, 'a', encoding='utf-8') as chat_file:
|
|
372
374
|
chat_file.write(write_content)
|
|
373
375
|
return True
|
|
376
|
+
|
|
377
|
+
def read_docx(self, file_path):
|
|
378
|
+
import docx
|
|
379
|
+
doc = docx.Document(file_path)
|
|
380
|
+
return '\n'.join(para.text for para in doc.paragraphs)
|
|
381
|
+
|
|
382
|
+
def read_pdf(self, file_path):
|
|
383
|
+
import pymupdf4llm
|
|
384
|
+
return pymupdf4llm.to_markdown(file_path, write_images=False)
|
|
385
|
+
|
|
386
|
+
def read_odt(self, file_path):
|
|
387
|
+
import pymupdf4llm
|
|
388
|
+
return pymupdf4llm.to_markdown(file_path, write_images=False)
|
|
389
|
+
|
|
390
|
+
@file_exists_check
|
|
391
|
+
def load_document_file(self, file_path: str, prefix: str = "", suffix: str = "", block_delimiter: str = "```"):
|
|
392
|
+
import os
|
|
393
|
+
|
|
394
|
+
_, ext = os.path.splitext(file_path)
|
|
395
|
+
ext = ext.lower()
|
|
396
|
+
|
|
397
|
+
text_content = ""
|
|
398
|
+
match ext:
|
|
399
|
+
case ".docx":
|
|
400
|
+
text_content = self.read_docx(file_path)
|
|
401
|
+
case ".pdf":
|
|
402
|
+
text_content = self.read_pdf(file_path)
|
|
403
|
+
case ".odt":
|
|
404
|
+
text_content = self.read_odt(file_path)
|
|
405
|
+
# Add more cases if needed.
|
|
406
|
+
case _:
|
|
407
|
+
print("Unsupported document type.")
|
|
408
|
+
return False
|
|
409
|
+
|
|
410
|
+
if block_delimiter:
|
|
411
|
+
text_content = f"{block_delimiter}\n{text_content}\n{block_delimiter}"
|
|
412
|
+
|
|
413
|
+
write_content = f"{prefix}{text_content}{suffix}\n"
|
|
414
|
+
|
|
415
|
+
with open(self.chat_name, 'a', encoding='utf-8') as chat_file:
|
|
416
|
+
chat_file.write(write_content)
|
|
417
|
+
return True
|
|
374
418
|
|
|
375
419
|
def load_file(self, file_name: str, prefix: str = "", suffix: str = "", block_delimiter: str = ""):
|
|
376
420
|
binary_type_mapping = Chat.BINARY_TYPE_MAPPING
|
|
421
|
+
document_type_extensions = Chat.DOCUMENT_TYPE_EXTENSIONS
|
|
377
422
|
|
|
378
423
|
file_type = None
|
|
379
424
|
file_name_lower = file_name.lower()
|
|
@@ -382,7 +427,16 @@ Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat
|
|
|
382
427
|
file_type = mime_type
|
|
383
428
|
break
|
|
384
429
|
|
|
385
|
-
|
|
430
|
+
is_file_document = any(file_name_lower.endswith(ext) for ext in document_type_extensions)
|
|
431
|
+
|
|
432
|
+
if is_file_document:
|
|
433
|
+
return self.load_document_file(
|
|
434
|
+
file_name=file_name,
|
|
435
|
+
prefix=prefix,
|
|
436
|
+
suffix=suffix,
|
|
437
|
+
block_delimiter=block_delimiter
|
|
438
|
+
)
|
|
439
|
+
elif file_type:
|
|
386
440
|
return self.load_binary_file(
|
|
387
441
|
file_name=file_name,
|
|
388
442
|
mime_type=file_type,
|
|
@@ -503,6 +557,19 @@ Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat
|
|
|
503
557
|
return False
|
|
504
558
|
return True
|
|
505
559
|
|
|
560
|
+
@cmd2.with_category(CATEGORY_CHAT_CONTROL)
|
|
561
|
+
def do_LOAD_DOCUMENT(self, file_name):
|
|
562
|
+
"""Load a document file (PDF, DOCX, DOC, ODT) and append its text content to chat file. Can be given the file name in-line. Will attempt to find the file relative to chat file first, then treat the given path as absolute"""
|
|
563
|
+
matching_files = self.find_matching_files_to_load(file_name)
|
|
564
|
+
if not matching_files:
|
|
565
|
+
return
|
|
566
|
+
|
|
567
|
+
for file_path in matching_files:
|
|
568
|
+
prefix = f"\nFile: {file_path}\n"
|
|
569
|
+
self.add_prompt_tag_if_needed(self.chat_name)
|
|
570
|
+
if not os.path.isdir(file_path) and self.load_document_file(file_path, prefix=prefix):
|
|
571
|
+
print(f"Loaded document file {file_path}")
|
|
572
|
+
|
|
506
573
|
@cmd2.with_category(CATEGORY_CHAT_CONTROL)
|
|
507
574
|
def do_LOAD_IMAGE(self, file_name):
|
|
508
575
|
"""Load an image file and append it to chat file. Can be given the file name in-line. Will attempt to find the file relative to chat file first, then treat the given path as absolute"""
|
ara_cli/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# version.py
|
|
2
|
-
__version__ = "0.1.9.
|
|
2
|
+
__version__ = "0.1.9.78" # fith parameter like .0 for local install test purposes only. official numbers should be 4 digit numbers
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ara_cli
|
|
3
|
+
Version: 0.1.9.78
|
|
4
|
+
Summary: Powerful, open source command-line tool for managing, structuring and automating software development artifacts in line with Business-Driven Development (BDD) and AI-assisted processes
|
|
5
|
+
Description-Content-Type: text/markdown
|
|
6
|
+
Requires-Dist: litellm
|
|
7
|
+
Requires-Dist: llama-index
|
|
8
|
+
Requires-Dist: llama-index-llms-openai
|
|
9
|
+
Requires-Dist: llama-index-retrievers-bm25
|
|
10
|
+
Requires-Dist: openai
|
|
11
|
+
Requires-Dist: markdown-it-py
|
|
12
|
+
Requires-Dist: json-repair
|
|
13
|
+
Requires-Dist: argparse
|
|
14
|
+
Requires-Dist: argcomplete
|
|
15
|
+
Requires-Dist: cmd2>=2.5
|
|
16
|
+
Requires-Dist: pydantic
|
|
17
|
+
Requires-Dist: pydantic_ai
|
|
18
|
+
Requires-Dist: python-docx
|
|
19
|
+
Requires-Dist: pymupdf4llm
|
|
20
|
+
Dynamic: description
|
|
21
|
+
Dynamic: description-content-type
|
|
22
|
+
Dynamic: requires-dist
|
|
23
|
+
Dynamic: summary
|
|
24
|
+
|
|
25
|
+
# ara-cli
|
|
26
|
+
|
|
27
|
+
**ara-cli** is a powerful, open source command-line tool for managing, structuring and automating software development artifacts in line with Business-Driven Development (BDD) and AI-assisted processes. With an intuitive interface and platform-independent implementation in Python, ara-cli enables teams to structure business goals, capabilities, features, user stories, and tasks, and to leverage integrated AI/chat capabilities for requirements engineering, documentation, and process automation.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Features
|
|
32
|
+
|
|
33
|
+
- **Comprehensive Artefact Management:**
|
|
34
|
+
Create, edit, rename, delete, and list all core artefacts of the software development lifecycle: businessgoals, vision, capabilities, keyfeatures, features, epics, userstories, examples, and tasks.
|
|
35
|
+
|
|
36
|
+
- **Structured Traceability:**
|
|
37
|
+
Organize and link artefacts for full traceability from business goals to implementation tasks. Effortlessly navigate artefact hierarchies and dependencies.
|
|
38
|
+
|
|
39
|
+
- **Integrated AI and Chat:**
|
|
40
|
+
Interact with AI language models directly from your terminal. Use chat and prompt commands to assist with documentation, requirements refinement, and artefact management.
|
|
41
|
+
|
|
42
|
+
- **Prompt Templates:**
|
|
43
|
+
Fetch, use, and manage reusable prompt templates for consistent and efficient requirements and documentation workflows.
|
|
44
|
+
|
|
45
|
+
- **Artefact Status and User Management:**
|
|
46
|
+
Assign and query status and responsible users for artefacts to support project coordination and tracking.
|
|
47
|
+
|
|
48
|
+
- **Automated Quality Assurance:**
|
|
49
|
+
Scan artefact trees for inconsistencies and automatically correct issues using integrated LLM-powered autofix functionality.
|
|
50
|
+
|
|
51
|
+
- **Powerful Listing and Search:**
|
|
52
|
+
List artefacts and filter by type, tags, content, contributor relationships, file extensions, and more.
|
|
53
|
+
|
|
54
|
+
- **Open Source & Platform Independent:**
|
|
55
|
+
Implemented in Python and available on PyPI for easy installation and integration into any workflow.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Use Cases
|
|
60
|
+
|
|
61
|
+
- **Requirements Engineering:**
|
|
62
|
+
Capture and structure business requirements and user stories with clear traceability.
|
|
63
|
+
|
|
64
|
+
- **Agile Development:**
|
|
65
|
+
Manage and automate backlog refinement, sprint planning, and task tracking.
|
|
66
|
+
|
|
67
|
+
- **AI-Enhanced Productivity:**
|
|
68
|
+
Use chat and prompt features to accelerate documentation, code review, and knowledge management.
|
|
69
|
+
|
|
70
|
+
- **Quality Management:**
|
|
71
|
+
Ensure artefact consistency and high documentation quality via automated scans and fixes.
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Quick Start
|
|
76
|
+
|
|
77
|
+
Install from PyPI:
|
|
78
|
+
```bash
|
|
79
|
+
pip install ara-cli
|
|
80
|
+
````
|
|
81
|
+
|
|
82
|
+
Create your first feature artefact:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
ara create feature login
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
List all features:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
ara list --include-extension .feature
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Chat with the integrated AI:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
ara chat
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Scan and autofix artefacts:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
ara scan
|
|
104
|
+
ara autofix
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Command Overview
|
|
110
|
+
|
|
111
|
+
| Action | Description |
|
|
112
|
+
|--------------------|-----------------------------------------------------------------------------|
|
|
113
|
+
| create | Create a classified artefact with data directory |
|
|
114
|
+
| delete | Delete an artefact and its data directory |
|
|
115
|
+
| rename | Rename an artefact and its data directory |
|
|
116
|
+
| list, list-tags | List artefacts, show tags, filter by content, extension, hierarchy etc. |
|
|
117
|
+
| prompt, chat | Use AI-powered chat and prompt templates for artefact management |
|
|
118
|
+
| template | Print artefact templates in the terminal |
|
|
119
|
+
| fetch-templates | Download and manage reusable prompt templates |
|
|
120
|
+
| read | Output artefact contents and their full contribution chain |
|
|
121
|
+
| reconnect | Connect artefacts to parent artefacts |
|
|
122
|
+
| read-status, set-status | Query and assign status to artefacts |
|
|
123
|
+
| read-user, set-user | Query and assign responsible users |
|
|
124
|
+
| classifier-directory | Show directory of artefact classifiers |
|
|
125
|
+
| scan | Scan the ARA tree for incompatible or inconsistent artefacts |
|
|
126
|
+
| autofix | Automatically correct artefact issues with LLM assistance |
|
|
127
|
+
|
|
128
|
+
See `ara -h` for the complete list of commands and usage examples.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Artefact Structure
|
|
133
|
+
|
|
134
|
+
ara-cli organizes your project artefacts in a clear directory structure:
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
./ara/
|
|
138
|
+
├── businessgoals/
|
|
139
|
+
├── vision/
|
|
140
|
+
├── capabilities/
|
|
141
|
+
├── keyfeatures/
|
|
142
|
+
├── features/
|
|
143
|
+
├── epics/
|
|
144
|
+
├── userstories/
|
|
145
|
+
├── examples/
|
|
146
|
+
├── tasks/
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Example Workflows
|
|
152
|
+
|
|
153
|
+
- **Create a new feature and link it to a user story:**
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
ara create feature payment contributes-to userstory checkout
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
- **Read an artefact's content and its full parent chain:**
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
ara read task implement_api --branch
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
- **List tasks containing specific content:**
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
ara list --include-extension .task --include-content "API integration"
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
- **Automate prompt-based LLM interaction for a task:**
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
ara prompt send task implement_api
|
|
175
|
+
ara prompt extract task implement_api
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Requirements
|
|
181
|
+
|
|
182
|
+
- Python 3.8+
|
|
183
|
+
- Platform-independent; tested on Linux, macOS, and Windows
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## License
|
|
188
|
+
|
|
189
|
+
This project is open source and freely available under the [MIT License](vector://vector/webapp/LICENSE).
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Links
|
|
194
|
+
|
|
195
|
+
- **PyPI:** https://pypi.org/project/ara-cli/
|
|
196
|
+
- **Source code:** \[GitHub link or repository URL\]
|
|
197
|
+
- **Documentation:** \[Link if available\]
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Contributing
|
|
202
|
+
|
|
203
|
+
Contributions, issues, and feature requests are welcome! Please open an issue or submit a pull request via GitHub.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
**ara-cli — Structure your development. Automate with AI. Build better software.**
|
|
208
|
+
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
ara_cli/__init__.py,sha256=0zl7IegxTid26EBGLav_fXZ4CCIV3H5TfAoFQiOHjvg,148
|
|
2
|
-
ara_cli/__main__.py,sha256=
|
|
2
|
+
ara_cli/__main__.py,sha256=ppfq0FIi4x6ONRzP67784A4BPo2labh8Bd_EExuXo4U,2011
|
|
3
3
|
ara_cli/ara_command_action.py,sha256=J613DUTjRxrPG8Jm-fJcIM0QlZTeULmq9Q7DKkDxJHg,22039
|
|
4
|
-
ara_cli/ara_command_parser.py,sha256=
|
|
4
|
+
ara_cli/ara_command_parser.py,sha256=vyxLELnyAZFC2C3v0hH4-r9QBmJ8oIs0hCZukkMFXfc,20136
|
|
5
5
|
ara_cli/ara_config.py,sha256=SgZfQVpqj5JJN4SB0n2IvAH0sKIdS3k1K1Zht2wDywA,8814
|
|
6
|
-
ara_cli/artefact_autofix.py,sha256=
|
|
6
|
+
ara_cli/artefact_autofix.py,sha256=WVTiIR-jo4YKmmz4eS3qTFvl45W1YKwAk1XSuz9QX10,20015
|
|
7
7
|
ara_cli/artefact_creator.py,sha256=0Ory6cB-Ahkw-BDNb8QHnTbp_OHGABdkb9bhwcEdcIc,6063
|
|
8
8
|
ara_cli/artefact_deleter.py,sha256=Co4wwCH3yW8H9NrOq7_2p5571EeHr0TsfE-H8KqoOfY,1900
|
|
9
9
|
ara_cli/artefact_fuzzy_search.py,sha256=iBlDqjZf-_D3VUjFf7ZwkiQbpQDcwRndIU7aG_sRTgE,2668
|
|
10
10
|
ara_cli/artefact_link_updater.py,sha256=nKdxTpDKqWTOAMD8viKmUaklSFGWzJZ8S8E8xW_ADuM,3775
|
|
11
11
|
ara_cli/artefact_lister.py,sha256=jhk4n4eqp7hDIq07q43QzS7-36BM3OfZ4EABxCeOGcw,4764
|
|
12
|
-
ara_cli/artefact_reader.py,sha256=
|
|
12
|
+
ara_cli/artefact_reader.py,sha256=Pho0_Eqm7kD9CNbVMhKb6mkNM0I3iJiCJXbXmVp1DJU,7827
|
|
13
13
|
ara_cli/artefact_renamer.py,sha256=Hnz_3zD9xxnBa1FHyUE6mIktLk_9ttP2rFRvQIkmz-o,4061
|
|
14
14
|
ara_cli/artefact_scan.py,sha256=msPCm-vPWOAZ_e_z5GylXxq1MtNlmJ4zvKrsdOFCWF4,4813
|
|
15
|
-
ara_cli/chat.py,sha256=
|
|
15
|
+
ara_cli/chat.py,sha256=Plje33XcOedSx-nmLCkuFIXSqHPIvMcy5I71xYWuYmU,31956
|
|
16
16
|
ara_cli/classifier.py,sha256=zWskj7rBYdqYBGjksBm46iTgVU5IIf2PZsJr4qeiwVU,1878
|
|
17
17
|
ara_cli/codefusionretriever.py,sha256=fCHgXdIBRzkVAnapX-KI2NQ44XbrrF4tEQmn5J6clUI,1980
|
|
18
18
|
ara_cli/codehierachieretriever.py,sha256=Xd3EgEWWhkSf1TmTWtf8X5_YvyE_4B66nRrqarwSiTU,1182
|
|
@@ -31,9 +31,9 @@ ara_cli/run_file_lister.py,sha256=XbrrDTJXp1LFGx9Lv91SNsEHZPP-PyEMBF_P4btjbDA,23
|
|
|
31
31
|
ara_cli/tag_extractor.py,sha256=TGdaQOVnjy25R0zDsAifB67C5oom0Fwo24s0_fr5A_I,3151
|
|
32
32
|
ara_cli/template_manager.py,sha256=YwrN6AYPpl6ZrW8BVQpVXx8yTRf-oNpJUIKeg4NAggs,6606
|
|
33
33
|
ara_cli/update_config_prompt.py,sha256=Oy9vNTw6UhDohyTEfSKkqE5ifEMPlmWNYkKHgUrK_pY,4607
|
|
34
|
-
ara_cli/version.py,sha256=
|
|
34
|
+
ara_cli/version.py,sha256=8uB-BYYtS-wDJMQLMNnX870pu9lmnUnQMT23kLhsfwE,146
|
|
35
35
|
ara_cli/artefact_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
-
ara_cli/artefact_models/artefact_load.py,sha256=
|
|
36
|
+
ara_cli/artefact_models/artefact_load.py,sha256=IXzWxP-Q_j_oDGMno0m-OuXCQ7Vd5c_NctshGr4ROBw,621
|
|
37
37
|
ara_cli/artefact_models/artefact_mapping.py,sha256=8aD0spBjkJ8toMAmFawc6UTUxB6-tEEViZXv2I-r88Q,1874
|
|
38
38
|
ara_cli/artefact_models/artefact_model.py,sha256=qSbcrmFWAYgBqcNl9QARI1_uLQJm-TPVgP5q2AEFnjE,15983
|
|
39
39
|
ara_cli/artefact_models/artefact_templates.py,sha256=8HNM-TsNvKgTpruOBs751yRDXJypTiJhc1tkWCiYG7s,9830
|
|
@@ -45,7 +45,7 @@ ara_cli/artefact_models/feature_artefact_model.py,sha256=FrR7_xydOmMySAz0QpWgrNF
|
|
|
45
45
|
ara_cli/artefact_models/issue_artefact_model.py,sha256=v6CpKnkqiUh6Wch2kkEmyyW49c8ysdy1qz8l1Ft9uJA,2552
|
|
46
46
|
ara_cli/artefact_models/keyfeature_artefact_model.py,sha256=J9oXLsCAo22AW31D5Z104y02ss0S0O4tPCcd09zYCD0,4066
|
|
47
47
|
ara_cli/artefact_models/serialize_helper.py,sha256=Wks30wy-UrwJURetydKykLgJkdGRgXFHkDT24vHe5tU,595
|
|
48
|
-
ara_cli/artefact_models/task_artefact_model.py,sha256=
|
|
48
|
+
ara_cli/artefact_models/task_artefact_model.py,sha256=1BSMbz9D-RXvdpdd0RlAr9hUx84Rcuysk2YfQC8Qy14,6046
|
|
49
49
|
ara_cli/artefact_models/userstory_artefact_model.py,sha256=2awH31ROtm7j4T44Bv4cylQDYLQtnfgXZMhDu_pgw-k,6435
|
|
50
50
|
ara_cli/artefact_models/vision_artefact_model.py,sha256=frjaUJj-mmIlVHEhzAQztCGs-CtvNu_odSborgztfzo,5251
|
|
51
51
|
ara_cli/templates/agile.artefacts,sha256=nTA8dp98HWKAD-0qhmNpVYIfkVGoJshZqMJGnphiOsE,7932
|
|
@@ -124,14 +124,14 @@ ara_cli/templates/specification_breakdown_files/template.technology.md,sha256=by
|
|
|
124
124
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
125
125
|
tests/test_ara_command_action.py,sha256=JTLqXM9BSMlU33OQgrk_sZnoowFJZKZAx8q-st-wa34,25821
|
|
126
126
|
tests/test_ara_config.py,sha256=pvkdPLTzgLkOijil0HaN0mhLC2Rdu4Fu5RfXEyOlRfs,16672
|
|
127
|
-
tests/test_artefact_autofix.py,sha256=
|
|
127
|
+
tests/test_artefact_autofix.py,sha256=pApZ-N0dW8Ujt-cNLbgvd4bhiIIK8oXb-saLf6QlA-8,25022
|
|
128
128
|
tests/test_artefact_fuzzy_search.py,sha256=5Sh3_l9QK8-WHn6JpGPU1b6h4QEnl2JoMq1Tdp2cj1U,1261
|
|
129
129
|
tests/test_artefact_link_updater.py,sha256=biqbEp2jCOz8giv72hu2P2hDfeJfJ9OrVGdAv5d9cK4,2191
|
|
130
130
|
tests/test_artefact_lister.py,sha256=VCEOCgDgnAOeUUgIoGAbWgz60hf9UT-tdHg18LGfB34,22656
|
|
131
131
|
tests/test_artefact_reader.py,sha256=660K-d8ed-j8hulsUB_7baPD2-hhbg9TffUR5yVc4Uo,927
|
|
132
132
|
tests/test_artefact_renamer.py,sha256=lSnKCCfoFGgKhTdDZrEaeBq1xJAak1QoqH5aSeOe9Ro,3494
|
|
133
133
|
tests/test_artefact_scan.py,sha256=uNWgrt7ieZ4ogKACsPqzAsh59JF2BhTKSag31hpVrTQ,16887
|
|
134
|
-
tests/test_chat.py,sha256=
|
|
134
|
+
tests/test_chat.py,sha256=fUGqpsyilLjwIFNlCAC69pYGEhwRuU6pplywwGJk-K8,54907
|
|
135
135
|
tests/test_classifier.py,sha256=grYGPksydNdPsaEBQxYHZTuTdcJWz7VQtikCKA6BNaQ,1920
|
|
136
136
|
tests/test_directory_navigator.py,sha256=7G0MVrBbtBvbrFUpL0zb_9EkEWi1dulWuHsrQxMJxDY,140
|
|
137
137
|
tests/test_file_classifier.py,sha256=kLWPiePu3F5mkVuI_lK_2QlLh2kXD_Mt2K8KZZ1fAnA,10940
|
|
@@ -141,8 +141,8 @@ tests/test_list_filter.py,sha256=fJA3d_SdaOAUkE7jn68MOVS0THXGghy1fye_64Zvo1U,796
|
|
|
141
141
|
tests/test_tag_extractor.py,sha256=nSiAYlTKZ7TLAOtcJpwK5zTWHhFYU0tI5xKnivLc1dU,2712
|
|
142
142
|
tests/test_template_manager.py,sha256=q-LMHRG4rHkD6ON6YW4cpZxUx9hul6Or8wVVRC2kb-8,4099
|
|
143
143
|
tests/test_update_config_prompt.py,sha256=xsqj1WTn4BsG5Q2t-sNPfu7EoMURFcS-hfb5VSXUnJc,6765
|
|
144
|
-
ara_cli-0.1.9.
|
|
145
|
-
ara_cli-0.1.9.
|
|
146
|
-
ara_cli-0.1.9.
|
|
147
|
-
ara_cli-0.1.9.
|
|
148
|
-
ara_cli-0.1.9.
|
|
144
|
+
ara_cli-0.1.9.78.dist-info/METADATA,sha256=j8cLr6oh3gVDON2FJE-pds7Psqspoxsgo008NV6btWw,6739
|
|
145
|
+
ara_cli-0.1.9.78.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
146
|
+
ara_cli-0.1.9.78.dist-info/entry_points.txt,sha256=v4h7MzysTgSIDYfEo3oj4Kz_8lzsRa3hq-KJHEcLVX8,45
|
|
147
|
+
ara_cli-0.1.9.78.dist-info/top_level.txt,sha256=WM4cLHT5DYUaWzLtRj-gu3yVNFpGQ6lLRI3FMmC-38I,14
|
|
148
|
+
ara_cli-0.1.9.78.dist-info/RECORD,,
|
tests/test_artefact_autofix.py
CHANGED
|
@@ -15,6 +15,7 @@ from ara_cli.artefact_autofix import (
|
|
|
15
15
|
_has_valid_contribution,
|
|
16
16
|
set_closest_contribution,
|
|
17
17
|
fix_contribution,
|
|
18
|
+
fix_rule
|
|
18
19
|
)
|
|
19
20
|
from ara_cli.artefact_models.artefact_model import Artefact, ArtefactType, Contribution
|
|
20
21
|
|
|
@@ -60,6 +61,24 @@ def mock_artefact_with_contribution():
|
|
|
60
61
|
return mock_artefact
|
|
61
62
|
|
|
62
63
|
|
|
64
|
+
@pytest.fixture
|
|
65
|
+
def mock_contribution():
|
|
66
|
+
m = MagicMock()
|
|
67
|
+
m.artefact_name = "parent_name"
|
|
68
|
+
m.classifier = "feature"
|
|
69
|
+
m.rule = "my_rule"
|
|
70
|
+
return m
|
|
71
|
+
|
|
72
|
+
@pytest.fixture
|
|
73
|
+
def mock_artefact(mock_contribution):
|
|
74
|
+
m = MagicMock()
|
|
75
|
+
m.contribution = mock_contribution
|
|
76
|
+
m._artefact_type.return_value.value = "requirement"
|
|
77
|
+
m.title = "my_title"
|
|
78
|
+
m.serialize.return_value = "serialized-text"
|
|
79
|
+
return m
|
|
80
|
+
|
|
81
|
+
|
|
63
82
|
def test_read_report_file_success():
|
|
64
83
|
"""Tests successful reading of the report file."""
|
|
65
84
|
mock_content = "# Artefact Check Report\n- `file.feature`: reason"
|
|
@@ -614,4 +633,72 @@ def test_apply_autofix_single_pass(
|
|
|
614
633
|
assert "Single-pass mode enabled" in output
|
|
615
634
|
assert "Attempt 1/1" in output
|
|
616
635
|
assert "Attempt 2/1" not in output
|
|
617
|
-
mock_check_file.assert_called_once()
|
|
636
|
+
mock_check_file.assert_called_once()
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
@patch("ara_cli.artefact_autofix._update_rule")
|
|
640
|
+
@patch("ara_cli.artefact_autofix.populate_classified_artefact_info")
|
|
641
|
+
def test_fix_rule_with_rule(mock_populate, mock_update_rule, mock_artefact, mock_contribution, capsys):
|
|
642
|
+
# Contribution has a rule
|
|
643
|
+
artefact_class = MagicMock()
|
|
644
|
+
artefact_class.deserialize.return_value = mock_artefact
|
|
645
|
+
mock_populate.return_value = {"info": "dummy"}
|
|
646
|
+
|
|
647
|
+
result = fix_rule(
|
|
648
|
+
file_path="dummy.feature",
|
|
649
|
+
artefact_text="text",
|
|
650
|
+
artefact_class=artefact_class,
|
|
651
|
+
classified_artefact_info={},
|
|
652
|
+
)
|
|
653
|
+
|
|
654
|
+
# deserialize called
|
|
655
|
+
artefact_class.deserialize.assert_called_once_with("text")
|
|
656
|
+
# _update_rule called with correct args
|
|
657
|
+
mock_update_rule.assert_called_once_with(
|
|
658
|
+
artefact=mock_artefact,
|
|
659
|
+
name="parent_name",
|
|
660
|
+
classifier="feature",
|
|
661
|
+
classified_file_info={"info": "dummy"},
|
|
662
|
+
delete_if_not_found=True,
|
|
663
|
+
)
|
|
664
|
+
# Feedback message contains rule
|
|
665
|
+
assert "with rule" in capsys.readouterr().out
|
|
666
|
+
# Result is the serialized text
|
|
667
|
+
assert result == "serialized-text"
|
|
668
|
+
|
|
669
|
+
@patch("ara_cli.artefact_autofix._update_rule")
|
|
670
|
+
@patch("ara_cli.artefact_autofix.populate_classified_artefact_info")
|
|
671
|
+
def test_fix_rule_without_rule(mock_populate, mock_update_rule, mock_artefact, mock_contribution, capsys):
|
|
672
|
+
# Contribution rule becomes None after update
|
|
673
|
+
mock_contribution.rule = None
|
|
674
|
+
artefact_class = MagicMock()
|
|
675
|
+
artefact_class.deserialize.return_value = mock_artefact
|
|
676
|
+
mock_populate.return_value = {"info": "dummy"}
|
|
677
|
+
|
|
678
|
+
result = fix_rule(
|
|
679
|
+
file_path="dummy.feature",
|
|
680
|
+
artefact_text="text",
|
|
681
|
+
artefact_class=artefact_class,
|
|
682
|
+
classified_artefact_info={},
|
|
683
|
+
)
|
|
684
|
+
|
|
685
|
+
# Feedback message says "without a rule"
|
|
686
|
+
assert "without a rule" in capsys.readouterr().out
|
|
687
|
+
assert result == "serialized-text"
|
|
688
|
+
|
|
689
|
+
@patch("ara_cli.artefact_autofix.populate_classified_artefact_info")
|
|
690
|
+
def test_fix_rule_contribution_none_raises(mock_populate):
|
|
691
|
+
# artefact.contribution is None: should assert
|
|
692
|
+
artefact = MagicMock()
|
|
693
|
+
artefact.contribution = None
|
|
694
|
+
artefact_class = MagicMock()
|
|
695
|
+
artefact_class.deserialize.return_value = artefact
|
|
696
|
+
mock_populate.return_value = {}
|
|
697
|
+
|
|
698
|
+
with pytest.raises(AssertionError):
|
|
699
|
+
fix_rule(
|
|
700
|
+
file_path="dummy.feature",
|
|
701
|
+
artefact_text="stuff",
|
|
702
|
+
artefact_class=artefact_class,
|
|
703
|
+
classified_artefact_info={},
|
|
704
|
+
)
|