ara-cli 0.1.9.93__py3-none-any.whl → 0.1.9.94__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.
- ara_cli/__init__.py +1 -1
- ara_cli/ara_command_action.py +23 -43
- ara_cli/ara_command_parser.py +16 -1
- ara_cli/artefact_lister.py +29 -55
- ara_cli/artefact_models/artefact_data_retrieval.py +23 -0
- ara_cli/artefact_renamer.py +6 -2
- ara_cli/chat.py +5 -2
- ara_cli/commands/extract_command.py +4 -3
- ara_cli/commands/read_command.py +104 -0
- ara_cli/prompt_extractor.py +21 -6
- ara_cli/tag_extractor.py +21 -11
- ara_cli/version.py +1 -1
- {ara_cli-0.1.9.93.dist-info → ara_cli-0.1.9.94.dist-info}/METADATA +17 -17
- {ara_cli-0.1.9.93.dist-info → ara_cli-0.1.9.94.dist-info}/RECORD +19 -17
- tests/test_artefact_lister.py +52 -132
- tests/test_chat.py +11 -10
- {ara_cli-0.1.9.93.dist-info → ara_cli-0.1.9.94.dist-info}/WHEEL +0 -0
- {ara_cli-0.1.9.93.dist-info → ara_cli-0.1.9.94.dist-info}/entry_points.txt +0 -0
- {ara_cli-0.1.9.93.dist-info → ara_cli-0.1.9.94.dist-info}/top_level.txt +0 -0
ara_cli/__init__.py
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
from .version import __version__
|
|
2
2
|
|
|
3
|
-
whitelisted_commands = ["RERUN", "SEND", "EXTRACT", "LOAD_IMAGE", "CHOOSE_MODEL", "CURRENT_MODEL", "LIST_MODELS"]
|
|
3
|
+
whitelisted_commands = ["RERUN", "SEND", "EXTRACT", "LOAD_IMAGE", "CHOOSE_MODEL", "CHOOSE_EXTRACTION_MODEL", "CURRENT_MODEL", "CURRENT_EXTRACTION_MODEL", "LIST_MODELS"]
|
ara_cli/ara_command_action.py
CHANGED
|
@@ -165,6 +165,7 @@ def prompt_action(args):
|
|
|
165
165
|
classifier = args.classifier
|
|
166
166
|
param = args.parameter
|
|
167
167
|
init = args.steps
|
|
168
|
+
write = getattr(args, 'write', False)
|
|
168
169
|
|
|
169
170
|
def handle_init():
|
|
170
171
|
from ara_cli.prompt_handler import initialize_prompt_templates
|
|
@@ -192,7 +193,7 @@ def prompt_action(args):
|
|
|
192
193
|
def handle_extract():
|
|
193
194
|
from ara_cli.prompt_extractor import extract_and_save_prompt_results
|
|
194
195
|
from ara_cli.update_config_prompt import update_artefact_config_prompt_files
|
|
195
|
-
extract_and_save_prompt_results(classifier, param)
|
|
196
|
+
extract_and_save_prompt_results(classifier, param, write=write)
|
|
196
197
|
print(f"automatic update after extract")
|
|
197
198
|
update_artefact_config_prompt_files(classifier, param, automatic_update=True)
|
|
198
199
|
|
|
@@ -294,53 +295,30 @@ def fetch_templates_action(args):
|
|
|
294
295
|
|
|
295
296
|
|
|
296
297
|
def read_action(args):
|
|
297
|
-
from ara_cli.
|
|
298
|
-
from ara_cli.
|
|
298
|
+
from ara_cli.commands.read_command import ReadCommand
|
|
299
|
+
from ara_cli.list_filter import ListFilter
|
|
299
300
|
|
|
300
301
|
classifier = args.classifier
|
|
301
302
|
artefact_name = args.parameter
|
|
302
303
|
read_mode = args.read_mode
|
|
303
304
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
all_artefact_names
|
|
313
|
-
)
|
|
314
|
-
return
|
|
315
|
-
|
|
316
|
-
target_artefact = next(filter(
|
|
317
|
-
lambda x: x.title == artefact_name, artefacts
|
|
318
|
-
))
|
|
305
|
+
list_filter = ListFilter(
|
|
306
|
+
include_content=args.include_content,
|
|
307
|
+
exclude_content=args.exclude_content,
|
|
308
|
+
include_extension=args.include_extension,
|
|
309
|
+
exclude_extension=args.exclude_extension,
|
|
310
|
+
include_tags=args.include_tags,
|
|
311
|
+
exclude_tags=args.exclude_tags
|
|
312
|
+
)
|
|
319
313
|
|
|
320
|
-
|
|
314
|
+
command = ReadCommand(
|
|
315
|
+
classifier=classifier,
|
|
316
|
+
artefact_name=artefact_name,
|
|
317
|
+
read_mode=read_mode,
|
|
318
|
+
list_filter=list_filter
|
|
319
|
+
)
|
|
321
320
|
|
|
322
|
-
|
|
323
|
-
case "branch":
|
|
324
|
-
ArtefactReader.step_through_value_chain(
|
|
325
|
-
artefact_name=artefact_name,
|
|
326
|
-
classifier=classifier,
|
|
327
|
-
artefacts_by_classifier=artefacts_by_classifier,
|
|
328
|
-
classified_artefacts=classified_artefacts
|
|
329
|
-
)
|
|
330
|
-
file_classifier.print_classified_files(artefacts_by_classifier, print_content=True)
|
|
331
|
-
case "children":
|
|
332
|
-
artefacts = ArtefactReader.find_children(
|
|
333
|
-
artefact_name=artefact_name,
|
|
334
|
-
classifier=classifier,
|
|
335
|
-
classified_artefacts=classified_artefacts
|
|
336
|
-
)
|
|
337
|
-
file_classifier.print_classified_files(
|
|
338
|
-
files_by_classifier=artefacts,
|
|
339
|
-
print_content=True
|
|
340
|
-
)
|
|
341
|
-
case _:
|
|
342
|
-
artefacts_by_classifier[classifier].append(target_artefact)
|
|
343
|
-
file_classifier.print_classified_files(artefacts_by_classifier, print_content=True)
|
|
321
|
+
command.execute()
|
|
344
322
|
|
|
345
323
|
|
|
346
324
|
def reconnect_action(args):
|
|
@@ -615,11 +593,13 @@ def extract_action(args):
|
|
|
615
593
|
from ara_cli.commands.extract_command import ExtractCommand
|
|
616
594
|
|
|
617
595
|
filename = args.filename
|
|
618
|
-
|
|
596
|
+
force = args.force
|
|
597
|
+
write = getattr(args, 'write', False)
|
|
619
598
|
print(filename)
|
|
620
599
|
command = ExtractCommand(
|
|
621
600
|
file_name=filename,
|
|
622
|
-
|
|
601
|
+
force=force,
|
|
602
|
+
write=write,
|
|
623
603
|
output=lambda msg: print(msg, file=sys.stdout),
|
|
624
604
|
error_output=lambda msg: print(msg, file=sys.stderr)
|
|
625
605
|
)
|
ara_cli/ara_command_parser.py
CHANGED
|
@@ -254,6 +254,13 @@ def prompt_parser(subparsers):
|
|
|
254
254
|
).completer = ArtefactCompleter()
|
|
255
255
|
if step == "chat":
|
|
256
256
|
add_chat_arguments(step_parser)
|
|
257
|
+
if step == "extract":
|
|
258
|
+
step_parser.add_argument(
|
|
259
|
+
"-w",
|
|
260
|
+
"--write",
|
|
261
|
+
action="store_true",
|
|
262
|
+
help="Overwrite existing files without using LLM for merging."
|
|
263
|
+
)
|
|
257
264
|
|
|
258
265
|
|
|
259
266
|
def chat_parser(subparsers):
|
|
@@ -287,6 +294,8 @@ def read_parser(subparsers):
|
|
|
287
294
|
"parameter", help="Filename of artefact"
|
|
288
295
|
).completer = ArtefactCompleter()
|
|
289
296
|
|
|
297
|
+
add_filter_flags(read_parser)
|
|
298
|
+
|
|
290
299
|
branch_group = read_parser.add_mutually_exclusive_group()
|
|
291
300
|
branch_group.add_argument(
|
|
292
301
|
"-b",
|
|
@@ -429,10 +438,16 @@ def extract_parser(subparsers):
|
|
|
429
438
|
help="Input file to extract from."
|
|
430
439
|
)
|
|
431
440
|
extract_parser.add_argument(
|
|
432
|
-
"--
|
|
441
|
+
"--force", "-f",
|
|
433
442
|
action="store_true",
|
|
434
443
|
help="Answer queries with yes when extracting."
|
|
435
444
|
)
|
|
445
|
+
extract_parser.add_argument(
|
|
446
|
+
"-w",
|
|
447
|
+
"--write",
|
|
448
|
+
action="store_true",
|
|
449
|
+
help="Overwrite existing files without using LLM for merging."
|
|
450
|
+
)
|
|
436
451
|
|
|
437
452
|
|
|
438
453
|
class CustomHelpFormatter(argparse.HelpFormatter):
|
ara_cli/artefact_lister.py
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
from ara_cli.file_classifier import FileClassifier
|
|
2
2
|
from ara_cli.artefact_reader import ArtefactReader
|
|
3
3
|
from ara_cli.file_lister import list_files_in_directory
|
|
4
|
-
from ara_cli.artefact_models.artefact_model import Artefact
|
|
5
4
|
from ara_cli.list_filter import ListFilter, filter_list
|
|
6
5
|
from ara_cli.artefact_fuzzy_search import suggest_close_name_matches
|
|
6
|
+
from ara_cli.artefact_models.artefact_data_retrieval import (
|
|
7
|
+
artefact_content_retrieval,
|
|
8
|
+
artefact_path_retrieval,
|
|
9
|
+
artefact_tags_retrieval,
|
|
10
|
+
)
|
|
7
11
|
import os
|
|
8
12
|
|
|
9
13
|
|
|
@@ -11,43 +15,18 @@ class ArtefactLister:
|
|
|
11
15
|
def __init__(self, file_system=None):
|
|
12
16
|
self.file_system = file_system or os
|
|
13
17
|
|
|
14
|
-
@staticmethod
|
|
15
|
-
def artefact_content_retrieval(artefact: Artefact):
|
|
16
|
-
content = artefact.serialize()
|
|
17
|
-
return content
|
|
18
|
-
|
|
19
|
-
@staticmethod
|
|
20
|
-
def artefact_path_retrieval(artefact: Artefact):
|
|
21
|
-
return artefact.file_path
|
|
22
|
-
|
|
23
|
-
@staticmethod
|
|
24
|
-
def artefact_tags_retrieval(artefact: Artefact):
|
|
25
|
-
final_tags = []
|
|
26
|
-
|
|
27
|
-
if not artefact:
|
|
28
|
-
return []
|
|
29
|
-
|
|
30
|
-
final_tags.extend([f"user_{user}" for user in artefact.users])
|
|
31
|
-
final_tags.append(artefact.status)
|
|
32
|
-
final_tags.extend(artefact.tags)
|
|
33
|
-
|
|
34
|
-
return final_tags
|
|
35
|
-
|
|
36
18
|
def filter_artefacts(self, classified_files: list, list_filter: ListFilter):
|
|
37
19
|
filtered_list = filter_list(
|
|
38
20
|
list_to_filter=classified_files,
|
|
39
21
|
list_filter=list_filter,
|
|
40
|
-
content_retrieval_strategy=
|
|
41
|
-
file_path_retrieval=
|
|
42
|
-
tag_retrieval=
|
|
22
|
+
content_retrieval_strategy=artefact_content_retrieval,
|
|
23
|
+
file_path_retrieval=artefact_path_retrieval,
|
|
24
|
+
tag_retrieval=artefact_tags_retrieval,
|
|
43
25
|
)
|
|
44
26
|
return filtered_list
|
|
45
27
|
|
|
46
28
|
def list_files(
|
|
47
|
-
self,
|
|
48
|
-
tags=None,
|
|
49
|
-
navigate_to_target=False,
|
|
50
|
-
list_filter: ListFilter | None = None
|
|
29
|
+
self, tags=None, navigate_to_target=False, list_filter: ListFilter | None = None
|
|
51
30
|
):
|
|
52
31
|
artefact_list = ArtefactReader.read_artefacts(tags=tags)
|
|
53
32
|
artefact_list = self.filter_artefacts(artefact_list, list_filter)
|
|
@@ -60,20 +39,18 @@ class ArtefactLister:
|
|
|
60
39
|
file_classifier.print_classified_files(filtered_artefact_list)
|
|
61
40
|
|
|
62
41
|
def list_branch(
|
|
63
|
-
self,
|
|
64
|
-
classifier,
|
|
65
|
-
artefact_name,
|
|
66
|
-
list_filter: ListFilter | None = None
|
|
42
|
+
self, classifier, artefact_name, list_filter: ListFilter | None = None
|
|
67
43
|
):
|
|
68
44
|
file_classifier = FileClassifier(os)
|
|
69
45
|
classified_artefacts = file_classifier.classify_files()
|
|
70
46
|
artefact_info = classified_artefacts.get(classifier, [])
|
|
71
|
-
matching_artefact_info = [
|
|
47
|
+
matching_artefact_info = [
|
|
48
|
+
p for p in artefact_info if p["title"] == artefact_name
|
|
49
|
+
]
|
|
72
50
|
|
|
73
51
|
if not matching_artefact_info:
|
|
74
52
|
suggest_close_name_matches(
|
|
75
|
-
artefact_name,
|
|
76
|
-
[info["title"] for info in artefact_info]
|
|
53
|
+
artefact_name, [info["title"] for info in artefact_info]
|
|
77
54
|
)
|
|
78
55
|
|
|
79
56
|
artefacts_by_classifier = {classifier: []}
|
|
@@ -82,29 +59,28 @@ class ArtefactLister:
|
|
|
82
59
|
classifier=classifier,
|
|
83
60
|
artefacts_by_classifier=artefacts_by_classifier,
|
|
84
61
|
)
|
|
85
|
-
artefacts_by_classifier = self.filter_artefacts(
|
|
62
|
+
artefacts_by_classifier = self.filter_artefacts(
|
|
63
|
+
artefacts_by_classifier, list_filter
|
|
64
|
+
)
|
|
86
65
|
file_classifier.print_classified_files(artefacts_by_classifier)
|
|
87
66
|
|
|
88
67
|
def list_children(
|
|
89
|
-
self,
|
|
90
|
-
classifier,
|
|
91
|
-
artefact_name,
|
|
92
|
-
list_filter: ListFilter | None = None
|
|
68
|
+
self, classifier, artefact_name, list_filter: ListFilter | None = None
|
|
93
69
|
):
|
|
94
70
|
file_classifier = FileClassifier(os)
|
|
95
71
|
classified_artefacts = file_classifier.classify_files()
|
|
96
72
|
artefact_info = classified_artefacts.get(classifier, [])
|
|
97
|
-
matching_artefact_info = [
|
|
73
|
+
matching_artefact_info = [
|
|
74
|
+
p for p in artefact_info if p["title"] == artefact_name
|
|
75
|
+
]
|
|
98
76
|
|
|
99
77
|
if not matching_artefact_info:
|
|
100
78
|
suggest_close_name_matches(
|
|
101
|
-
artefact_name,
|
|
102
|
-
[info["title"] for info in artefact_info]
|
|
79
|
+
artefact_name, [info["title"] for info in artefact_info]
|
|
103
80
|
)
|
|
104
81
|
|
|
105
82
|
child_artefacts = ArtefactReader.find_children(
|
|
106
|
-
artefact_name=artefact_name,
|
|
107
|
-
classifier=classifier
|
|
83
|
+
artefact_name=artefact_name, classifier=classifier
|
|
108
84
|
)
|
|
109
85
|
|
|
110
86
|
child_artefacts = self.filter_artefacts(child_artefacts, list_filter)
|
|
@@ -112,25 +88,23 @@ class ArtefactLister:
|
|
|
112
88
|
file_classifier.print_classified_files(child_artefacts)
|
|
113
89
|
|
|
114
90
|
def list_data(
|
|
115
|
-
self,
|
|
116
|
-
classifier,
|
|
117
|
-
artefact_name,
|
|
118
|
-
list_filter: ListFilter | None = None
|
|
91
|
+
self, classifier, artefact_name, list_filter: ListFilter | None = None
|
|
119
92
|
):
|
|
120
93
|
file_classifier = FileClassifier(os)
|
|
121
94
|
classified_artefact_info = file_classifier.classify_files()
|
|
122
95
|
artefact_info_dict = classified_artefact_info.get(classifier, [])
|
|
123
96
|
|
|
124
|
-
matching_info = [
|
|
97
|
+
matching_info = [
|
|
98
|
+
info for info in artefact_info_dict if info["title"] == artefact_name
|
|
99
|
+
]
|
|
125
100
|
|
|
126
101
|
if not matching_info:
|
|
127
102
|
suggest_close_name_matches(
|
|
128
|
-
artefact_name,
|
|
129
|
-
[info["title"] for info in artefact_info_dict]
|
|
103
|
+
artefact_name, [info["title"] for info in artefact_info_dict]
|
|
130
104
|
)
|
|
131
105
|
return
|
|
132
106
|
|
|
133
107
|
artefact_info = matching_info[0]
|
|
134
|
-
data_dir = os.path.splitext(artefact_info["file_path"])[0] +
|
|
108
|
+
data_dir = os.path.splitext(artefact_info["file_path"])[0] + ".data"
|
|
135
109
|
if os.path.exists(data_dir):
|
|
136
110
|
list_files_in_directory(data_dir, list_filter)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from ara_cli.artefact_models.artefact_model import Artefact
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def artefact_content_retrieval(artefact: Artefact):
|
|
5
|
+
content = artefact.serialize()
|
|
6
|
+
return content
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def artefact_path_retrieval(artefact: Artefact):
|
|
10
|
+
return artefact.file_path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def artefact_tags_retrieval(artefact: Artefact):
|
|
14
|
+
final_tags = []
|
|
15
|
+
|
|
16
|
+
if not artefact:
|
|
17
|
+
return []
|
|
18
|
+
|
|
19
|
+
final_tags.extend([f"user_{user}" for user in artefact.users])
|
|
20
|
+
final_tags.append(artefact.status)
|
|
21
|
+
final_tags.extend(artefact.tags)
|
|
22
|
+
|
|
23
|
+
return final_tags
|
ara_cli/artefact_renamer.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import os
|
|
2
1
|
from functools import lru_cache
|
|
3
2
|
from ara_cli.classifier import Classifier
|
|
4
3
|
from ara_cli.artefact_link_updater import ArtefactLinkUpdater
|
|
5
4
|
from ara_cli.template_manager import DirectoryNavigator
|
|
5
|
+
import os
|
|
6
6
|
import re
|
|
7
|
+
import warnings
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
class ArtefactRenamer:
|
|
@@ -22,6 +23,8 @@ class ArtefactRenamer:
|
|
|
22
23
|
return re.compile(pattern)
|
|
23
24
|
|
|
24
25
|
def rename(self, old_name, new_name, classifier):
|
|
26
|
+
import shutil
|
|
27
|
+
|
|
25
28
|
original_directory = self.navigate_to_target()
|
|
26
29
|
|
|
27
30
|
if not new_name:
|
|
@@ -47,7 +50,8 @@ class ArtefactRenamer:
|
|
|
47
50
|
if self.file_system.path.exists(new_file_path):
|
|
48
51
|
raise FileExistsError(f"The new file name {new_file_path} already exists.")
|
|
49
52
|
if self.file_system.path.exists(new_dir_path):
|
|
50
|
-
|
|
53
|
+
warnings.warn(f"The new directory name {new_dir_path} already exists. It will be replaced by the artefact's data directory or removed entirely.", UserWarning)
|
|
54
|
+
shutil.rmtree(new_dir_path)
|
|
51
55
|
|
|
52
56
|
# Perform the renaming of the file and directory
|
|
53
57
|
self.file_system.rename(old_file_path, new_file_path)
|
ara_cli/chat.py
CHANGED
|
@@ -9,13 +9,15 @@ from ara_cli.file_loaders.text_file_loader import TextFileLoader
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
extract_parser = argparse.ArgumentParser()
|
|
12
|
-
extract_parser.add_argument('-
|
|
12
|
+
extract_parser.add_argument('-f', '--force', action='store_true', help='Force extraction')
|
|
13
|
+
extract_parser.add_argument('-w','--write', action='store_true', help='Overwrite existing files without using LLM for merging.')
|
|
13
14
|
|
|
14
15
|
load_parser = argparse.ArgumentParser()
|
|
15
16
|
load_parser.add_argument('file_name', nargs='?', default='', help='File to load')
|
|
16
17
|
load_parser.add_argument('--load-images', action='store_true', help='Extract and describe images from documents')
|
|
17
18
|
|
|
18
19
|
|
|
20
|
+
|
|
19
21
|
class Chat(cmd2.Cmd):
|
|
20
22
|
CATEGORY_CHAT_CONTROL = "Chat control commands"
|
|
21
23
|
CATEGORY_LLM_CONTROL = "Language model controls"
|
|
@@ -813,7 +815,8 @@ Start chatting (type 'HELP'/'h' for available commands, 'QUIT'/'q' to exit chat
|
|
|
813
815
|
|
|
814
816
|
command = ExtractCommand(
|
|
815
817
|
file_name=self.chat_name,
|
|
816
|
-
|
|
818
|
+
force=args.force,
|
|
819
|
+
write=args.write,
|
|
817
820
|
output=self.poutput,
|
|
818
821
|
error_output=self.perror
|
|
819
822
|
)
|
|
@@ -3,15 +3,16 @@ from ara_cli.prompt_extractor import extract_responses
|
|
|
3
3
|
import os
|
|
4
4
|
|
|
5
5
|
class ExtractCommand(Command):
|
|
6
|
-
def __init__(self, file_name,
|
|
6
|
+
def __init__(self, file_name, force=False, write=False, output=None, error_output=None):
|
|
7
7
|
self.file_name = file_name
|
|
8
|
-
self.
|
|
8
|
+
self.force = force
|
|
9
|
+
self.write = write
|
|
9
10
|
self.output = output # Callable for standard output (optional)
|
|
10
11
|
self.error_output = error_output # Callable for errors (optional)
|
|
11
12
|
|
|
12
13
|
def execute(self, *args, **kwargs):
|
|
13
14
|
try:
|
|
14
|
-
extract_responses(self.file_name, True,
|
|
15
|
+
extract_responses(self.file_name, True, force=self.force, write=self.write)
|
|
15
16
|
if self.output:
|
|
16
17
|
self.output("End of extraction")
|
|
17
18
|
except Exception as e:
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
from ara_cli.commands.command import Command
|
|
2
|
+
from ara_cli.artefact_reader import ArtefactReader
|
|
3
|
+
from ara_cli.file_classifier import FileClassifier
|
|
4
|
+
from ara_cli.list_filter import ListFilter, filter_list
|
|
5
|
+
from ara_cli.artefact_models.artefact_data_retrieval import (
|
|
6
|
+
artefact_content_retrieval,
|
|
7
|
+
artefact_path_retrieval,
|
|
8
|
+
artefact_tags_retrieval
|
|
9
|
+
)
|
|
10
|
+
from ara_cli.artefact_fuzzy_search import suggest_close_name_matches
|
|
11
|
+
import os
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class ReadCommand(Command):
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
classifier: str,
|
|
18
|
+
artefact_name: str,
|
|
19
|
+
read_mode: str = "default",
|
|
20
|
+
list_filter: ListFilter = None,
|
|
21
|
+
output=None
|
|
22
|
+
):
|
|
23
|
+
self.classifier = classifier
|
|
24
|
+
self.artefact_name = artefact_name
|
|
25
|
+
self.read_mode = read_mode
|
|
26
|
+
self.list_filter = list_filter or ListFilter()
|
|
27
|
+
self.output = output or print
|
|
28
|
+
|
|
29
|
+
def execute(self) -> bool:
|
|
30
|
+
"""Execute the read command and return success status."""
|
|
31
|
+
file_classifier = FileClassifier(os)
|
|
32
|
+
classified_artefacts = ArtefactReader.read_artefacts()
|
|
33
|
+
artefacts = classified_artefacts.get(self.classifier, [])
|
|
34
|
+
all_artefact_names = [a.title for a in artefacts]
|
|
35
|
+
|
|
36
|
+
if self.artefact_name not in all_artefact_names:
|
|
37
|
+
suggest_close_name_matches(
|
|
38
|
+
self.artefact_name,
|
|
39
|
+
all_artefact_names
|
|
40
|
+
)
|
|
41
|
+
return False
|
|
42
|
+
|
|
43
|
+
target_artefact = next(filter(
|
|
44
|
+
lambda x: x.title == self.artefact_name, artefacts
|
|
45
|
+
))
|
|
46
|
+
|
|
47
|
+
artefacts_by_classifier = {self.classifier: []}
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
match self.read_mode:
|
|
51
|
+
case "branch":
|
|
52
|
+
self._handle_branch_mode(
|
|
53
|
+
classified_artefacts, artefacts_by_classifier
|
|
54
|
+
)
|
|
55
|
+
case "children":
|
|
56
|
+
artefacts_by_classifier = self._handle_children_mode(
|
|
57
|
+
classified_artefacts
|
|
58
|
+
)
|
|
59
|
+
case _:
|
|
60
|
+
self._handle_default_mode(
|
|
61
|
+
target_artefact, artefacts_by_classifier
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Apply filtering and print results
|
|
65
|
+
filtered_artefacts = self._apply_filtering(artefacts_by_classifier)
|
|
66
|
+
file_classifier.print_classified_files(
|
|
67
|
+
filtered_artefacts, print_content=True
|
|
68
|
+
)
|
|
69
|
+
return True
|
|
70
|
+
|
|
71
|
+
except Exception as e:
|
|
72
|
+
self.output(f"Error reading artefact: {e}")
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
def _handle_branch_mode(self, classified_artefacts, artefacts_by_classifier):
|
|
76
|
+
"""Handle branch read mode."""
|
|
77
|
+
ArtefactReader.step_through_value_chain(
|
|
78
|
+
artefact_name=self.artefact_name,
|
|
79
|
+
classifier=self.classifier,
|
|
80
|
+
artefacts_by_classifier=artefacts_by_classifier,
|
|
81
|
+
classified_artefacts=classified_artefacts
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
def _handle_children_mode(self, classified_artefacts):
|
|
85
|
+
"""Handle children read mode."""
|
|
86
|
+
return ArtefactReader.find_children(
|
|
87
|
+
artefact_name=self.artefact_name,
|
|
88
|
+
classifier=self.classifier,
|
|
89
|
+
classified_artefacts=classified_artefacts
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
def _handle_default_mode(self, target_artefact, artefacts_by_classifier):
|
|
93
|
+
"""Handle default read mode."""
|
|
94
|
+
artefacts_by_classifier[self.classifier].append(target_artefact)
|
|
95
|
+
|
|
96
|
+
def _apply_filtering(self, artefacts_by_classifier):
|
|
97
|
+
"""Apply list filtering to artefacts."""
|
|
98
|
+
return filter_list(
|
|
99
|
+
list_to_filter=artefacts_by_classifier,
|
|
100
|
+
list_filter=self.list_filter,
|
|
101
|
+
content_retrieval_strategy=artefact_content_retrieval,
|
|
102
|
+
file_path_retrieval=artefact_path_retrieval,
|
|
103
|
+
tag_retrieval=artefact_tags_retrieval
|
|
104
|
+
)
|
ara_cli/prompt_extractor.py
CHANGED
|
@@ -16,7 +16,7 @@ def extract_code_blocks_md(markdown_text):
|
|
|
16
16
|
return code_blocks
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
def extract_responses(document_path, relative_to_ara_root=False,
|
|
19
|
+
def extract_responses(document_path, relative_to_ara_root=False, force=False, write=False):
|
|
20
20
|
print(f"Debug: Starting extraction from {document_path}")
|
|
21
21
|
block_extraction_counter = 0
|
|
22
22
|
|
|
@@ -50,7 +50,7 @@ def extract_responses(document_path, relative_to_ara_root=False, skip_queries=Fa
|
|
|
50
50
|
block_lines = block_lines[1:] # Remove first line again after removing filename line
|
|
51
51
|
block = '\n'.join(block_lines)
|
|
52
52
|
|
|
53
|
-
handle_existing_file(file_path, block,
|
|
53
|
+
handle_existing_file(file_path, block, force, write)
|
|
54
54
|
block_extraction_counter += 1
|
|
55
55
|
|
|
56
56
|
# Update the markdown content
|
|
@@ -79,7 +79,7 @@ def extract_responses(document_path, relative_to_ara_root=False, skip_queries=Fa
|
|
|
79
79
|
artefact_path = artefact.file_path
|
|
80
80
|
directory = os.path.dirname(artefact_path)
|
|
81
81
|
os.makedirs(directory, exist_ok=True)
|
|
82
|
-
handle_existing_file(artefact_path, serialized_artefact,
|
|
82
|
+
handle_existing_file(artefact_path, serialized_artefact, force, write)
|
|
83
83
|
|
|
84
84
|
os.chdir(original_directory)
|
|
85
85
|
|
|
@@ -182,13 +182,28 @@ def create_prompt_for_file_modification(content_str, filename):
|
|
|
182
182
|
return prompt_text
|
|
183
183
|
|
|
184
184
|
|
|
185
|
-
def handle_existing_file(filename, block_content, skip_query=False):
|
|
185
|
+
def handle_existing_file(filename, block_content, skip_query=False, write=False):
|
|
186
186
|
if not os.path.isfile(filename):
|
|
187
187
|
print(f"File {filename} does not exist, attempting to create")
|
|
188
188
|
create_file_if_not_exist(filename, block_content, skip_query)
|
|
189
|
+
elif write:
|
|
190
|
+
print(f"File {filename} exists. Overwriting without LLM merge as requested.")
|
|
191
|
+
try:
|
|
192
|
+
directory = os.path.dirname(filename)
|
|
193
|
+
if directory:
|
|
194
|
+
os.makedirs(directory, exist_ok=True)
|
|
195
|
+
with open(filename, 'w', encoding='utf-8', errors='replace') as file:
|
|
196
|
+
file.write(block_content)
|
|
197
|
+
print(f"File {filename} overwritten successfully.")
|
|
198
|
+
except OSError as e:
|
|
199
|
+
print(f"Error: {e}")
|
|
200
|
+
print(f"Failed to overwrite file {filename} due to an OS error")
|
|
189
201
|
else:
|
|
190
202
|
print(f"File {filename} exists, creating modification prompt")
|
|
191
203
|
prompt_text = create_prompt_for_file_modification(block_content, filename)
|
|
204
|
+
if prompt_text is None:
|
|
205
|
+
return
|
|
206
|
+
|
|
192
207
|
messages = [{"role": "user", "content": prompt_text}]
|
|
193
208
|
response = ""
|
|
194
209
|
|
|
@@ -199,12 +214,12 @@ def handle_existing_file(filename, block_content, skip_query=False):
|
|
|
199
214
|
modify_and_save_file(response, filename)
|
|
200
215
|
|
|
201
216
|
|
|
202
|
-
def extract_and_save_prompt_results(classifier, param):
|
|
217
|
+
def extract_and_save_prompt_results(classifier, param, write=False):
|
|
203
218
|
sub_directory = Classifier.get_sub_directory(classifier)
|
|
204
219
|
prompt_log_file = f"ara/{sub_directory}/{param}.data/{classifier}.prompt_log.md"
|
|
205
220
|
print(f"Extract marked sections from: {prompt_log_file}")
|
|
206
221
|
|
|
207
|
-
extract_responses(prompt_log_file)
|
|
222
|
+
extract_responses(prompt_log_file, write=write)
|
|
208
223
|
|
|
209
224
|
|
|
210
225
|
def update_markdown(original_content, block_content, filename):
|
ara_cli/tag_extractor.py
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from ara_cli.list_filter import ListFilter, filter_list
|
|
3
|
-
from ara_cli.
|
|
3
|
+
from ara_cli.artefact_models.artefact_data_retrieval import (
|
|
4
|
+
artefact_content_retrieval,
|
|
5
|
+
artefact_path_retrieval,
|
|
6
|
+
artefact_tags_retrieval,
|
|
7
|
+
)
|
|
4
8
|
|
|
5
9
|
|
|
6
10
|
class TagExtractor:
|
|
@@ -10,7 +14,9 @@ class TagExtractor:
|
|
|
10
14
|
def filter_column(self, tags_set, filtered_artefacts):
|
|
11
15
|
status_tags = {"to-do", "in-progress", "review", "done", "closed"}
|
|
12
16
|
|
|
13
|
-
artefacts_to_process = self._get_artefacts_without_status_tags(
|
|
17
|
+
artefacts_to_process = self._get_artefacts_without_status_tags(
|
|
18
|
+
filtered_artefacts, status_tags
|
|
19
|
+
)
|
|
14
20
|
self._add_non_status_tags_to_set(tags_set, artefacts_to_process, status_tags)
|
|
15
21
|
|
|
16
22
|
def _get_artefacts_without_status_tags(self, filtered_artefacts, status_tags):
|
|
@@ -28,7 +34,9 @@ class TagExtractor:
|
|
|
28
34
|
|
|
29
35
|
def _add_non_status_tags_to_set(self, tags_set, artefacts, status_tags):
|
|
30
36
|
for artefact in artefacts:
|
|
31
|
-
tags = [
|
|
37
|
+
tags = [
|
|
38
|
+
tag for tag in (artefact.tags + [artefact.status]) if tag is not None
|
|
39
|
+
]
|
|
32
40
|
for tag in tags:
|
|
33
41
|
if self._is_skipped_tag(tag, status_tags):
|
|
34
42
|
continue
|
|
@@ -36,23 +44,25 @@ class TagExtractor:
|
|
|
36
44
|
|
|
37
45
|
def _is_skipped_tag(self, tag, status_tags):
|
|
38
46
|
return (
|
|
39
|
-
tag in status_tags
|
|
40
|
-
or tag.startswith("priority_")
|
|
41
|
-
or tag.startswith("user_")
|
|
47
|
+
tag in status_tags or tag.startswith("priority_") or tag.startswith("user_")
|
|
42
48
|
)
|
|
43
49
|
|
|
44
50
|
def add_to_tags_set(self, tags_set, filtered_artefacts):
|
|
45
51
|
for artefact_list in filtered_artefacts.values():
|
|
46
52
|
for artefact in artefact_list:
|
|
47
53
|
user_tags = [f"user_{tag}" for tag in artefact.users]
|
|
48
|
-
tags = [
|
|
54
|
+
tags = [
|
|
55
|
+
tag
|
|
56
|
+
for tag in (artefact.tags + [artefact.status] + user_tags)
|
|
57
|
+
if tag is not None
|
|
58
|
+
]
|
|
49
59
|
tags_set.update(tags)
|
|
50
60
|
|
|
51
61
|
def extract_tags(
|
|
52
62
|
self,
|
|
53
63
|
navigate_to_target=False,
|
|
54
64
|
filtered_extra_column=False,
|
|
55
|
-
list_filter: ListFilter | None = None
|
|
65
|
+
list_filter: ListFilter | None = None,
|
|
56
66
|
):
|
|
57
67
|
from ara_cli.template_manager import DirectoryNavigator
|
|
58
68
|
from ara_cli.artefact_reader import ArtefactReader
|
|
@@ -66,9 +76,9 @@ class TagExtractor:
|
|
|
66
76
|
filtered_artefacts = filter_list(
|
|
67
77
|
list_to_filter=artefacts,
|
|
68
78
|
list_filter=list_filter,
|
|
69
|
-
content_retrieval_strategy=
|
|
70
|
-
file_path_retrieval=
|
|
71
|
-
tag_retrieval=
|
|
79
|
+
content_retrieval_strategy=artefact_content_retrieval,
|
|
80
|
+
file_path_retrieval=artefact_path_retrieval,
|
|
81
|
+
tag_retrieval=artefact_tags_retrieval,
|
|
72
82
|
)
|
|
73
83
|
|
|
74
84
|
unique_tags = set()
|
ara_cli/version.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# version.py
|
|
2
|
-
__version__ = "0.1.9.
|
|
2
|
+
__version__ = "0.1.9.94" # fith parameter like .0 for local install test purposes only. official numbers should be 4 digit numbers
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ara_cli
|
|
3
|
-
Version: 0.1.9.
|
|
3
|
+
Version: 0.1.9.94
|
|
4
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
5
|
Description-Content-Type: text/markdown
|
|
6
6
|
Requires-Dist: litellm
|
|
@@ -108,22 +108,22 @@ ara autofix
|
|
|
108
108
|
|
|
109
109
|
## Command Overview
|
|
110
110
|
|
|
111
|
-
| Action
|
|
112
|
-
|
|
113
|
-
| create
|
|
114
|
-
| delete
|
|
115
|
-
| rename
|
|
116
|
-
| list, list-tags
|
|
117
|
-
| prompt, chat
|
|
118
|
-
| template
|
|
119
|
-
| fetch-templates
|
|
120
|
-
| read
|
|
121
|
-
| reconnect
|
|
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
|
|
126
|
-
| autofix
|
|
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
127
|
|
|
128
128
|
See `ara -h` for the complete list of commands and usage examples.
|
|
129
129
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
ara_cli/__init__.py,sha256=
|
|
1
|
+
ara_cli/__init__.py,sha256=oieeo07y5FLq0tmPzWZdp65j6tN8NOucSjSzrJw8qrQ,203
|
|
2
2
|
ara_cli/__main__.py,sha256=J5DCDLRZ6UcpYwM1-NkjaLo4PTetcSj2dB4HrrftkUw,2064
|
|
3
|
-
ara_cli/ara_command_action.py,sha256=
|
|
4
|
-
ara_cli/ara_command_parser.py,sha256=
|
|
3
|
+
ara_cli/ara_command_action.py,sha256=uyMN05ZYffWqN9nwL53MmQ_yHpuxHVqZ_scAMEoD1jw,21516
|
|
4
|
+
ara_cli/ara_command_parser.py,sha256=A1lMc9Gc0EMJt-380PTcv3aKoxbXGfx5gGax-sZqV3I,21020
|
|
5
5
|
ara_cli/ara_config.py,sha256=5uBo_flNgZSk7B9lmyfvzWyxfIQzb13LbieCpJfdZJI,8765
|
|
6
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
|
-
ara_cli/artefact_lister.py,sha256=
|
|
11
|
+
ara_cli/artefact_lister.py,sha256=M-ggazAgZ-OLeW9NB48r_sd6zPx0p4hEpeS63qHwI1A,4176
|
|
12
12
|
ara_cli/artefact_reader.py,sha256=Pho0_Eqm7kD9CNbVMhKb6mkNM0I3iJiCJXbXmVp1DJU,7827
|
|
13
|
-
ara_cli/artefact_renamer.py,sha256=
|
|
13
|
+
ara_cli/artefact_renamer.py,sha256=8S4QWD19_FGKsKlWojnu_RUOxx0u9rmLugydM4s4VDc,4219
|
|
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=t17TCmx9xvKj5wrnUOJBqjWoSjEVOFrVd8RivChVX50,37980
|
|
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
|
|
@@ -24,15 +24,16 @@ ara_cli/filename_validator.py,sha256=Aw9PL8d5-Ymhp3EY6lDrUBk3cudaNqo1Uw5RzPpI1jA
|
|
|
24
24
|
ara_cli/list_filter.py,sha256=qKGwwQsrWe7L5FbdxEbBYD1bbbi8c-RMypjXqXvLbgs,5291
|
|
25
25
|
ara_cli/output_suppressor.py,sha256=nwiHaQLwabOjMoJOeUESBnZszGMxrQZfJ3N2OvahX7Y,389
|
|
26
26
|
ara_cli/prompt_chat.py,sha256=kd_OINDQFit6jN04bb7mzgY259JBbRaTaNp9F-webkc,1346
|
|
27
|
-
ara_cli/prompt_extractor.py,sha256
|
|
27
|
+
ara_cli/prompt_extractor.py,sha256=-_17aVYXYH6kPX5FOSb9T8lbEkKPXE6nlHWq1pvO_Og,8423
|
|
28
28
|
ara_cli/prompt_handler.py,sha256=6yfiMFNHGHANREAsjT8dv9jKxBKeazPkF7xQQI4l6vQ,22312
|
|
29
29
|
ara_cli/prompt_rag.py,sha256=ydlhe4CUqz0jdzlY7jBbpKaf_5fjMrAZKnriKea3ZAg,7485
|
|
30
30
|
ara_cli/run_file_lister.py,sha256=XbrrDTJXp1LFGx9Lv91SNsEHZPP-PyEMBF_P4btjbDA,2360
|
|
31
|
-
ara_cli/tag_extractor.py,sha256=
|
|
31
|
+
ara_cli/tag_extractor.py,sha256=k2yRl7dAMZ4YTARzUke4wgY0oEIOmWkOHGet7nXB6uw,3317
|
|
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=MWb524qaDHLrSJsHhOq7o0m78CPLFil9qeyel6kPW-A,146
|
|
35
35
|
ara_cli/artefact_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
+
ara_cli/artefact_models/artefact_data_retrieval.py,sha256=CooXOJBYWSyiViN2xkC8baS8OUaslry3YGVVUeDxRAU,527
|
|
36
37
|
ara_cli/artefact_models/artefact_load.py,sha256=IXzWxP-Q_j_oDGMno0m-OuXCQ7Vd5c_NctshGr4ROBw,621
|
|
37
38
|
ara_cli/artefact_models/artefact_mapping.py,sha256=8aD0spBjkJ8toMAmFawc6UTUxB6-tEEViZXv2I-r88Q,1874
|
|
38
39
|
ara_cli/artefact_models/artefact_model.py,sha256=qSbcrmFWAYgBqcNl9QARI1_uLQJm-TPVgP5q2AEFnjE,15983
|
|
@@ -50,9 +51,10 @@ ara_cli/artefact_models/userstory_artefact_model.py,sha256=2awH31ROtm7j4T44Bv4cy
|
|
|
50
51
|
ara_cli/artefact_models/vision_artefact_model.py,sha256=frjaUJj-mmIlVHEhzAQztCGs-CtvNu_odSborgztfzo,5251
|
|
51
52
|
ara_cli/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
52
53
|
ara_cli/commands/command.py,sha256=Y_2dNeuxRjbyI3ScXNv55lptSe8Hs_ya78L0nPYNZHA,154
|
|
53
|
-
ara_cli/commands/extract_command.py,sha256=
|
|
54
|
+
ara_cli/commands/extract_command.py,sha256=qpi2_ac3DyxS7FiOz4GsTtRR4xtpegckUmfXzDOwymM,858
|
|
54
55
|
ara_cli/commands/load_command.py,sha256=H3CfeHIL-criDU5oi4BONTSpyzJ4m8DzJ0ZCIiAZFeI,2204
|
|
55
56
|
ara_cli/commands/load_image_command.py,sha256=g9-PXAYdqx5Ed1PdVo-FIb4CyJGEpRFbgQf9Dxg6DmM,886
|
|
57
|
+
ara_cli/commands/read_command.py,sha256=bo1BvRWuNKdFqBNN1EWORNrX_yuFAOyBruDUolHq1Vc,3791
|
|
56
58
|
ara_cli/file_loaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
57
59
|
ara_cli/file_loaders/binary_file_loader.py,sha256=1HHH1Nk4lEM83CTnf4z9wYz6rMLgpxydFoRcSgkBHmQ,940
|
|
58
60
|
ara_cli/file_loaders/document_file_loader.py,sha256=VxGFChYyM9K-e6eOCK3yk5jQuEXgz01Mh_NoA6CA_RM,1017
|
|
@@ -138,11 +140,11 @@ tests/test_ara_config.py,sha256=H5GwDbab0GMSa6IbHdruzmbsHy5Ia0xX0uteJdfZ9Rg,1427
|
|
|
138
140
|
tests/test_artefact_autofix.py,sha256=pApZ-N0dW8Ujt-cNLbgvd4bhiIIK8oXb-saLf6QlA-8,25022
|
|
139
141
|
tests/test_artefact_fuzzy_search.py,sha256=5Sh3_l9QK8-WHn6JpGPU1b6h4QEnl2JoMq1Tdp2cj1U,1261
|
|
140
142
|
tests/test_artefact_link_updater.py,sha256=biqbEp2jCOz8giv72hu2P2hDfeJfJ9OrVGdAv5d9cK4,2191
|
|
141
|
-
tests/test_artefact_lister.py,sha256=
|
|
143
|
+
tests/test_artefact_lister.py,sha256=35R13UU-YsX1HOsEN8M2-vIiCUA9RSBm6SwestDaFhE,20388
|
|
142
144
|
tests/test_artefact_reader.py,sha256=660K-d8ed-j8hulsUB_7baPD2-hhbg9TffUR5yVc4Uo,927
|
|
143
145
|
tests/test_artefact_renamer.py,sha256=lSnKCCfoFGgKhTdDZrEaeBq1xJAak1QoqH5aSeOe9Ro,3494
|
|
144
146
|
tests/test_artefact_scan.py,sha256=uNWgrt7ieZ4ogKACsPqzAsh59JF2BhTKSag31hpVrTQ,16887
|
|
145
|
-
tests/test_chat.py,sha256
|
|
147
|
+
tests/test_chat.py,sha256=cCNIuYiSGoNtjgjyFiTvkMHJgCmMNXQhpawNc23-fmM,57037
|
|
146
148
|
tests/test_classifier.py,sha256=grYGPksydNdPsaEBQxYHZTuTdcJWz7VQtikCKA6BNaQ,1920
|
|
147
149
|
tests/test_directory_navigator.py,sha256=7G0MVrBbtBvbrFUpL0zb_9EkEWi1dulWuHsrQxMJxDY,140
|
|
148
150
|
tests/test_file_classifier.py,sha256=kLWPiePu3F5mkVuI_lK_2QlLh2kXD_Mt2K8KZZ1fAnA,10940
|
|
@@ -153,8 +155,8 @@ tests/test_prompt_handler.py,sha256=3-lYBvyHLQgD29MODkXB3YylUWXmRCYdAwrQrtlW8WU,
|
|
|
153
155
|
tests/test_tag_extractor.py,sha256=nSiAYlTKZ7TLAOtcJpwK5zTWHhFYU0tI5xKnivLc1dU,2712
|
|
154
156
|
tests/test_template_manager.py,sha256=q-LMHRG4rHkD6ON6YW4cpZxUx9hul6Or8wVVRC2kb-8,4099
|
|
155
157
|
tests/test_update_config_prompt.py,sha256=xsqj1WTn4BsG5Q2t-sNPfu7EoMURFcS-hfb5VSXUnJc,6765
|
|
156
|
-
ara_cli-0.1.9.
|
|
157
|
-
ara_cli-0.1.9.
|
|
158
|
-
ara_cli-0.1.9.
|
|
159
|
-
ara_cli-0.1.9.
|
|
160
|
-
ara_cli-0.1.9.
|
|
158
|
+
ara_cli-0.1.9.94.dist-info/METADATA,sha256=CPz0aDXI8_4hJtbN9tm56-aNUNEum3G01dD9DMIwGdg,6755
|
|
159
|
+
ara_cli-0.1.9.94.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
160
|
+
ara_cli-0.1.9.94.dist-info/entry_points.txt,sha256=v4h7MzysTgSIDYfEo3oj4Kz_8lzsRa3hq-KJHEcLVX8,45
|
|
161
|
+
ara_cli-0.1.9.94.dist-info/top_level.txt,sha256=WM4cLHT5DYUaWzLtRj-gu3yVNFpGQ6lLRI3FMmC-38I,14
|
|
162
|
+
ara_cli-0.1.9.94.dist-info/RECORD,,
|
tests/test_artefact_lister.py
CHANGED
|
@@ -2,6 +2,11 @@ import pytest
|
|
|
2
2
|
from unittest.mock import MagicMock, patch
|
|
3
3
|
from ara_cli.artefact_lister import ArtefactLister
|
|
4
4
|
from ara_cli.list_filter import ListFilter
|
|
5
|
+
from ara_cli.artefact_models.artefact_data_retrieval import (
|
|
6
|
+
artefact_content_retrieval,
|
|
7
|
+
artefact_path_retrieval,
|
|
8
|
+
artefact_tags_retrieval,
|
|
9
|
+
)
|
|
5
10
|
|
|
6
11
|
|
|
7
12
|
@pytest.fixture
|
|
@@ -9,66 +14,6 @@ def artefact_lister():
|
|
|
9
14
|
return ArtefactLister()
|
|
10
15
|
|
|
11
16
|
|
|
12
|
-
@pytest.mark.parametrize(
|
|
13
|
-
"users, status, tags, expected_tags",
|
|
14
|
-
[
|
|
15
|
-
# Normal case with all fields populated
|
|
16
|
-
(
|
|
17
|
-
["john", "alice"],
|
|
18
|
-
"in-progress",
|
|
19
|
-
["important", "urgent"],
|
|
20
|
-
["user_john", "user_alice", "in-progress", "important", "urgent"]
|
|
21
|
-
),
|
|
22
|
-
# Case with empty users
|
|
23
|
-
(
|
|
24
|
-
[],
|
|
25
|
-
"to-do",
|
|
26
|
-
["feature", "backend"],
|
|
27
|
-
["to-do", "feature", "backend"]
|
|
28
|
-
),
|
|
29
|
-
# Case with empty tags
|
|
30
|
-
(
|
|
31
|
-
["bob"],
|
|
32
|
-
"done",
|
|
33
|
-
[],
|
|
34
|
-
["user_bob", "done"]
|
|
35
|
-
),
|
|
36
|
-
# Case with all empty fields
|
|
37
|
-
(
|
|
38
|
-
[],
|
|
39
|
-
"",
|
|
40
|
-
[],
|
|
41
|
-
[""]
|
|
42
|
-
),
|
|
43
|
-
# Case with None values for tags (should handle gracefully)
|
|
44
|
-
(
|
|
45
|
-
["admin"],
|
|
46
|
-
"closed",
|
|
47
|
-
None,
|
|
48
|
-
["user_admin", "closed"]
|
|
49
|
-
),
|
|
50
|
-
]
|
|
51
|
-
)
|
|
52
|
-
def test_artefact_tags_retrieval(users, status, tags, expected_tags):
|
|
53
|
-
# Create a mock artefact with the specified attributes
|
|
54
|
-
artefact_mock = MagicMock()
|
|
55
|
-
artefact_mock.users = users
|
|
56
|
-
artefact_mock.status = status
|
|
57
|
-
artefact_mock.tags = tags if tags is not None else []
|
|
58
|
-
|
|
59
|
-
# Call the method under test
|
|
60
|
-
result = ArtefactLister.artefact_tags_retrieval(artefact_mock)
|
|
61
|
-
|
|
62
|
-
# Verify the result
|
|
63
|
-
assert result == expected_tags
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def test_artefact_tags_retrieval_with_none():
|
|
67
|
-
# Test with None artefact
|
|
68
|
-
result = ArtefactLister.artefact_tags_retrieval(None)
|
|
69
|
-
assert result == []
|
|
70
|
-
|
|
71
|
-
|
|
72
17
|
@pytest.mark.parametrize(
|
|
73
18
|
"classified_files, list_filter, filter_result",
|
|
74
19
|
[
|
|
@@ -76,39 +21,36 @@ def test_artefact_tags_retrieval_with_none():
|
|
|
76
21
|
(
|
|
77
22
|
{"type1": [MagicMock(), MagicMock()]},
|
|
78
23
|
None,
|
|
79
|
-
{"type1": [MagicMock(), MagicMock()]}
|
|
24
|
+
{"type1": [MagicMock(), MagicMock()]},
|
|
80
25
|
),
|
|
81
26
|
# Case 2: Filter with include tags
|
|
82
27
|
(
|
|
83
28
|
{"type1": [MagicMock(), MagicMock()]},
|
|
84
29
|
ListFilter(include_tags=["tag1"]),
|
|
85
|
-
{"type1": [MagicMock()]}
|
|
30
|
+
{"type1": [MagicMock()]},
|
|
86
31
|
),
|
|
87
32
|
# Case 3: Filter with exclude tags
|
|
88
33
|
(
|
|
89
34
|
{"type1": [MagicMock(), MagicMock()], "type2": [MagicMock()]},
|
|
90
35
|
ListFilter(exclude_tags=["tag2"]),
|
|
91
|
-
{"type1": [MagicMock()], "type2": []}
|
|
36
|
+
{"type1": [MagicMock()], "type2": []},
|
|
92
37
|
),
|
|
93
38
|
# Case 4: Empty result after filtering
|
|
94
39
|
(
|
|
95
40
|
{"type1": [MagicMock(), MagicMock()]},
|
|
96
41
|
ListFilter(include_tags=["nonexistent"]),
|
|
97
|
-
{"type1": []}
|
|
42
|
+
{"type1": []},
|
|
98
43
|
),
|
|
99
44
|
# Case 5: Multiple artefact types
|
|
100
45
|
(
|
|
101
46
|
{"type1": [MagicMock()], "type2": [MagicMock(), MagicMock()]},
|
|
102
47
|
ListFilter(exclude_extension=[".txt"]),
|
|
103
|
-
{"type1": [], "type2": [MagicMock()]}
|
|
48
|
+
{"type1": [], "type2": [MagicMock()]},
|
|
104
49
|
),
|
|
105
50
|
],
|
|
106
51
|
)
|
|
107
52
|
def test_filter_artefacts(
|
|
108
|
-
artefact_lister,
|
|
109
|
-
classified_files,
|
|
110
|
-
list_filter,
|
|
111
|
-
filter_result
|
|
53
|
+
artefact_lister, classified_files, list_filter, filter_result
|
|
112
54
|
):
|
|
113
55
|
# Mock the filter_list function
|
|
114
56
|
with patch("ara_cli.artefact_lister.filter_list") as mock_filter_list:
|
|
@@ -121,9 +63,9 @@ def test_filter_artefacts(
|
|
|
121
63
|
mock_filter_list.assert_called_once_with(
|
|
122
64
|
list_to_filter=classified_files,
|
|
123
65
|
list_filter=list_filter,
|
|
124
|
-
content_retrieval_strategy=
|
|
125
|
-
file_path_retrieval=
|
|
126
|
-
tag_retrieval=
|
|
66
|
+
content_retrieval_strategy=artefact_content_retrieval,
|
|
67
|
+
file_path_retrieval=artefact_path_retrieval,
|
|
68
|
+
tag_retrieval=artefact_tags_retrieval,
|
|
127
69
|
)
|
|
128
70
|
|
|
129
71
|
# Verify the structure matches (don't compare the actual MagicMock objects)
|
|
@@ -132,30 +74,6 @@ def test_filter_artefacts(
|
|
|
132
74
|
assert len(result[key]) == len(filter_result[key])
|
|
133
75
|
|
|
134
76
|
|
|
135
|
-
@pytest.mark.parametrize("artefact_content", ["content1", "content2", "content3"])
|
|
136
|
-
def test_artefact_content_retrieval(artefact_content):
|
|
137
|
-
artefact_mock = MagicMock()
|
|
138
|
-
artefact_mock.serialize.return_value = artefact_content # Mock serialize()
|
|
139
|
-
|
|
140
|
-
content = ArtefactLister.artefact_content_retrieval(artefact_mock)
|
|
141
|
-
assert content == artefact_content
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
@pytest.mark.parametrize(
|
|
145
|
-
"file_path",
|
|
146
|
-
[
|
|
147
|
-
("./ara/userstories/test.userstory"),
|
|
148
|
-
("./ara/epics/test.epic"),
|
|
149
|
-
],
|
|
150
|
-
)
|
|
151
|
-
def test_artefact_path_retrieval(file_path):
|
|
152
|
-
artefact_mock = MagicMock()
|
|
153
|
-
artefact_mock.file_path = file_path
|
|
154
|
-
|
|
155
|
-
path = ArtefactLister.artefact_path_retrieval(artefact_mock)
|
|
156
|
-
assert path == file_path
|
|
157
|
-
|
|
158
|
-
|
|
159
77
|
@pytest.mark.parametrize(
|
|
160
78
|
"tags, navigate_to_target, list_filter, mock_artefacts, filtered_artefacts, expected_filtered",
|
|
161
79
|
[
|
|
@@ -476,20 +394,21 @@ def test_list_data_artefact_found_data_exists(artefact_lister):
|
|
|
476
394
|
classified_artefacts = {
|
|
477
395
|
"epic": [
|
|
478
396
|
{"title": "Epic1", "file_path": "path/to/Epic1.epic"},
|
|
479
|
-
{"title": "Epic2", "file_path": "path/to/Epic2.epic"}
|
|
397
|
+
{"title": "Epic2", "file_path": "path/to/Epic2.epic"},
|
|
480
398
|
]
|
|
481
399
|
}
|
|
482
|
-
|
|
483
|
-
with patch("ara_cli.artefact_lister.FileClassifier") as mock_file_classifier,
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
400
|
+
|
|
401
|
+
with patch("ara_cli.artefact_lister.FileClassifier") as mock_file_classifier, patch(
|
|
402
|
+
"ara_cli.artefact_lister.suggest_close_name_matches"
|
|
403
|
+
) as mock_suggest, patch("ara_cli.artefact_lister.os") as mock_os, patch(
|
|
404
|
+
"ara_cli.artefact_lister.list_files_in_directory"
|
|
405
|
+
) as mock_list_files:
|
|
487
406
|
|
|
488
407
|
# Configure mocks
|
|
489
408
|
mock_classifier_instance = MagicMock()
|
|
490
409
|
mock_file_classifier.return_value = mock_classifier_instance
|
|
491
410
|
mock_classifier_instance.classify_files.return_value = classified_artefacts
|
|
492
|
-
|
|
411
|
+
|
|
493
412
|
mock_os.path.splitext.return_value = ("path/to/Epic1", ".epic")
|
|
494
413
|
mock_os.path.exists.return_value = True
|
|
495
414
|
|
|
@@ -510,20 +429,21 @@ def test_list_data_artefact_found_data_not_exists(artefact_lister):
|
|
|
510
429
|
classified_artefacts = {
|
|
511
430
|
"epic": [
|
|
512
431
|
{"title": "Epic1", "file_path": "path/to/Epic1.epic"},
|
|
513
|
-
{"title": "Epic2", "file_path": "path/to/Epic2.epic"}
|
|
432
|
+
{"title": "Epic2", "file_path": "path/to/Epic2.epic"},
|
|
514
433
|
]
|
|
515
434
|
}
|
|
516
|
-
|
|
517
|
-
with patch("ara_cli.artefact_lister.FileClassifier") as mock_file_classifier,
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
435
|
+
|
|
436
|
+
with patch("ara_cli.artefact_lister.FileClassifier") as mock_file_classifier, patch(
|
|
437
|
+
"ara_cli.artefact_lister.suggest_close_name_matches"
|
|
438
|
+
) as mock_suggest, patch("ara_cli.artefact_lister.os") as mock_os, patch(
|
|
439
|
+
"ara_cli.artefact_lister.list_files_in_directory"
|
|
440
|
+
) as mock_list_files:
|
|
521
441
|
|
|
522
442
|
# Configure mocks
|
|
523
443
|
mock_classifier_instance = MagicMock()
|
|
524
444
|
mock_file_classifier.return_value = mock_classifier_instance
|
|
525
445
|
mock_classifier_instance.classify_files.return_value = classified_artefacts
|
|
526
|
-
|
|
446
|
+
|
|
527
447
|
mock_os.path.splitext.return_value = ("path/to/Epic1", ".epic")
|
|
528
448
|
mock_os.path.exists.return_value = False
|
|
529
449
|
|
|
@@ -544,14 +464,15 @@ def test_list_data_artefact_not_found(artefact_lister):
|
|
|
544
464
|
classified_artefacts = {
|
|
545
465
|
"epic": [
|
|
546
466
|
{"title": "Epic1", "file_path": "path/to/Epic1.epic"},
|
|
547
|
-
{"title": "Epic2", "file_path": "path/to/Epic2.epic"}
|
|
467
|
+
{"title": "Epic2", "file_path": "path/to/Epic2.epic"},
|
|
548
468
|
]
|
|
549
469
|
}
|
|
550
|
-
|
|
551
|
-
with patch("ara_cli.artefact_lister.FileClassifier") as mock_file_classifier,
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
470
|
+
|
|
471
|
+
with patch("ara_cli.artefact_lister.FileClassifier") as mock_file_classifier, patch(
|
|
472
|
+
"ara_cli.artefact_lister.suggest_close_name_matches"
|
|
473
|
+
) as mock_suggest, patch("ara_cli.artefact_lister.os") as mock_os, patch(
|
|
474
|
+
"ara_cli.artefact_lister.list_files_in_directory"
|
|
475
|
+
) as mock_list_files:
|
|
555
476
|
|
|
556
477
|
# Configure mocks
|
|
557
478
|
mock_classifier_instance = MagicMock()
|
|
@@ -562,10 +483,7 @@ def test_list_data_artefact_not_found(artefact_lister):
|
|
|
562
483
|
artefact_lister.list_data(classifier, artefact_name, list_filter)
|
|
563
484
|
|
|
564
485
|
# Verify interactions
|
|
565
|
-
mock_suggest.assert_called_once_with(
|
|
566
|
-
artefact_name,
|
|
567
|
-
["Epic1", "Epic2"]
|
|
568
|
-
)
|
|
486
|
+
mock_suggest.assert_called_once_with(artefact_name, ["Epic1", "Epic2"])
|
|
569
487
|
mock_os.path.splitext.assert_not_called()
|
|
570
488
|
mock_os.path.exists.assert_not_called()
|
|
571
489
|
mock_list_files.assert_not_called()
|
|
@@ -578,20 +496,21 @@ def test_list_data_with_filter(artefact_lister):
|
|
|
578
496
|
classified_artefacts = {
|
|
579
497
|
"userstory": [
|
|
580
498
|
{"title": "Story1", "file_path": "path/to/Story1.userstory"},
|
|
581
|
-
{"title": "Story2", "file_path": "path/to/Story2.userstory"}
|
|
499
|
+
{"title": "Story2", "file_path": "path/to/Story2.userstory"},
|
|
582
500
|
]
|
|
583
501
|
}
|
|
584
|
-
|
|
585
|
-
with patch("ara_cli.artefact_lister.FileClassifier") as mock_file_classifier,
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
502
|
+
|
|
503
|
+
with patch("ara_cli.artefact_lister.FileClassifier") as mock_file_classifier, patch(
|
|
504
|
+
"ara_cli.artefact_lister.suggest_close_name_matches"
|
|
505
|
+
) as mock_suggest, patch("ara_cli.artefact_lister.os") as mock_os, patch(
|
|
506
|
+
"ara_cli.artefact_lister.list_files_in_directory"
|
|
507
|
+
) as mock_list_files:
|
|
589
508
|
|
|
590
509
|
# Configure mocks
|
|
591
510
|
mock_classifier_instance = MagicMock()
|
|
592
511
|
mock_file_classifier.return_value = mock_classifier_instance
|
|
593
512
|
mock_classifier_instance.classify_files.return_value = classified_artefacts
|
|
594
|
-
|
|
513
|
+
|
|
595
514
|
mock_os.path.splitext.return_value = ("path/to/Story1", ".userstory")
|
|
596
515
|
mock_os.path.exists.return_value = True
|
|
597
516
|
|
|
@@ -610,11 +529,12 @@ def test_list_data_empty_artefact_list(artefact_lister):
|
|
|
610
529
|
artefact_name = "Epic1"
|
|
611
530
|
list_filter = None
|
|
612
531
|
classified_artefacts = {"epic": []}
|
|
613
|
-
|
|
614
|
-
with patch("ara_cli.artefact_lister.FileClassifier") as mock_file_classifier,
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
532
|
+
|
|
533
|
+
with patch("ara_cli.artefact_lister.FileClassifier") as mock_file_classifier, patch(
|
|
534
|
+
"ara_cli.artefact_lister.suggest_close_name_matches"
|
|
535
|
+
) as mock_suggest, patch("ara_cli.artefact_lister.os") as mock_os, patch(
|
|
536
|
+
"ara_cli.artefact_lister.list_files_in_directory"
|
|
537
|
+
) as mock_list_files:
|
|
618
538
|
|
|
619
539
|
# Configure mocks
|
|
620
540
|
mock_classifier_instance = MagicMock()
|
tests/test_chat.py
CHANGED
|
@@ -635,14 +635,14 @@ def test_load_file(temp_chat_file, file_name, file_type, mime_type):
|
|
|
635
635
|
patch.object(chat, 'load_text_file', return_value=True) as mock_load_text, \
|
|
636
636
|
patch.object(chat, 'load_document_file', return_value=True) as mock_load_document:
|
|
637
637
|
|
|
638
|
-
chat.load_file(file_name=file_name, prefix="p-", suffix="-
|
|
638
|
+
chat.load_file(file_name=file_name, prefix="p-", suffix="-f", block_delimiter="b", extract_images=False)
|
|
639
639
|
|
|
640
640
|
if file_type == "binary":
|
|
641
641
|
mock_load_binary.assert_called_once_with(
|
|
642
642
|
file_path=file_name,
|
|
643
643
|
mime_type=mime_type,
|
|
644
644
|
prefix="p-",
|
|
645
|
-
suffix="-
|
|
645
|
+
suffix="-f"
|
|
646
646
|
)
|
|
647
647
|
mock_load_text.assert_not_called()
|
|
648
648
|
mock_load_document.assert_not_called()
|
|
@@ -652,7 +652,7 @@ def test_load_file(temp_chat_file, file_name, file_type, mime_type):
|
|
|
652
652
|
mock_load_document.assert_called_once_with(
|
|
653
653
|
file_path=file_name,
|
|
654
654
|
prefix="p-",
|
|
655
|
-
suffix="-
|
|
655
|
+
suffix="-f",
|
|
656
656
|
block_delimiter="b",
|
|
657
657
|
extract_images=False
|
|
658
658
|
)
|
|
@@ -661,7 +661,7 @@ def test_load_file(temp_chat_file, file_name, file_type, mime_type):
|
|
|
661
661
|
mock_load_text.assert_called_once_with(
|
|
662
662
|
file_path=file_name,
|
|
663
663
|
prefix="p-",
|
|
664
|
-
suffix="-
|
|
664
|
+
suffix="-f",
|
|
665
665
|
block_delimiter="b",
|
|
666
666
|
extract_images=False
|
|
667
667
|
)
|
|
@@ -714,7 +714,7 @@ def test_load_helper(monkeypatch, capsys, temp_chat_file, directory, pattern, fi
|
|
|
714
714
|
def mock_input(prompt):
|
|
715
715
|
return user_input
|
|
716
716
|
|
|
717
|
-
def mock_load_file(self, file_path
|
|
717
|
+
def mock_load_file(self, file_path):
|
|
718
718
|
return True
|
|
719
719
|
|
|
720
720
|
monkeypatch.setattr(glob, 'glob', mock_glob)
|
|
@@ -750,7 +750,7 @@ def test_load_helper_with_exclude(monkeypatch, capsys, temp_chat_file, directory
|
|
|
750
750
|
def mock_input(prompt):
|
|
751
751
|
return user_input
|
|
752
752
|
|
|
753
|
-
def mock_load_file(self, file_path
|
|
753
|
+
def mock_load_file(self, file_path):
|
|
754
754
|
return True
|
|
755
755
|
|
|
756
756
|
monkeypatch.setattr(glob, 'glob', mock_glob)
|
|
@@ -907,7 +907,7 @@ def test_load_image(capsys, temp_chat_file, file_name, is_image, expected_mime):
|
|
|
907
907
|
chat = Chat(temp_chat_file.name, reset=False)
|
|
908
908
|
|
|
909
909
|
with patch.object(chat, 'load_binary_file', return_value=True) as mock_load_binary:
|
|
910
|
-
chat.load_image(file_name=file_name, prefix="p-", suffix="-
|
|
910
|
+
chat.load_image(file_name=file_name, prefix="p-", suffix="-f")
|
|
911
911
|
|
|
912
912
|
if is_image:
|
|
913
913
|
# FIX: The called method's parameter is `file_path`, not `file_name`.
|
|
@@ -915,7 +915,7 @@ def test_load_image(capsys, temp_chat_file, file_name, is_image, expected_mime):
|
|
|
915
915
|
file_path=file_name,
|
|
916
916
|
mime_type=expected_mime,
|
|
917
917
|
prefix="p-",
|
|
918
|
-
suffix="-
|
|
918
|
+
suffix="-f"
|
|
919
919
|
)
|
|
920
920
|
else:
|
|
921
921
|
mock_load_binary.assert_not_called()
|
|
@@ -1232,13 +1232,14 @@ def test_do_EXTRACT(MockExtractCommand, temp_chat_file):
|
|
|
1232
1232
|
with patch('ara_cli.prompt_handler.ConfigManager.get_config', return_value=mock_config):
|
|
1233
1233
|
chat = Chat(temp_chat_file.name, reset=False)
|
|
1234
1234
|
|
|
1235
|
-
#
|
|
1235
|
+
# The `onecmd_plus_hooks` method requires the `orig_rl_history_length` argument.
|
|
1236
1236
|
# We can pass a dummy value like 0 for the test.
|
|
1237
1237
|
chat.onecmd_plus_hooks("EXTRACT", orig_rl_history_length=0)
|
|
1238
1238
|
|
|
1239
1239
|
MockExtractCommand.assert_called_once_with(
|
|
1240
1240
|
file_name=chat.chat_name,
|
|
1241
|
-
|
|
1241
|
+
force=False,
|
|
1242
|
+
write=False,
|
|
1242
1243
|
output=chat.poutput,
|
|
1243
1244
|
error_output=chat.perror
|
|
1244
1245
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|