ara-cli 0.1.13.3__py3-none-any.whl → 0.1.14.0__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 +162 -112
- ara_cli/ara_config.py +1 -1
- ara_cli/ara_subcommands/convert.py +66 -2
- ara_cli/ara_subcommands/prompt.py +266 -106
- ara_cli/artefact_autofix.py +2 -2
- ara_cli/artefact_converter.py +152 -53
- ara_cli/artefact_creator.py +41 -17
- ara_cli/artefact_lister.py +3 -3
- ara_cli/artefact_models/artefact_model.py +1 -1
- ara_cli/artefact_models/artefact_templates.py +0 -9
- ara_cli/artefact_models/feature_artefact_model.py +8 -8
- ara_cli/artefact_reader.py +62 -43
- ara_cli/artefact_scan.py +39 -17
- ara_cli/chat.py +23 -15
- ara_cli/children_contribution_updater.py +737 -0
- ara_cli/classifier.py +34 -0
- ara_cli/commands/load_command.py +4 -3
- ara_cli/commands/load_image_command.py +1 -1
- ara_cli/commands/read_command.py +23 -27
- ara_cli/completers.py +24 -0
- ara_cli/error_handler.py +26 -11
- ara_cli/file_loaders/document_reader.py +0 -178
- ara_cli/file_loaders/factories/__init__.py +0 -0
- ara_cli/file_loaders/factories/document_reader_factory.py +32 -0
- ara_cli/file_loaders/factories/file_loader_factory.py +27 -0
- ara_cli/file_loaders/file_loader.py +1 -30
- ara_cli/file_loaders/loaders/__init__.py +0 -0
- ara_cli/file_loaders/{document_file_loader.py → loaders/document_file_loader.py} +1 -1
- ara_cli/file_loaders/loaders/text_file_loader.py +47 -0
- ara_cli/file_loaders/readers/__init__.py +0 -0
- ara_cli/file_loaders/readers/docx_reader.py +49 -0
- ara_cli/file_loaders/readers/excel_reader.py +27 -0
- ara_cli/file_loaders/{markdown_reader.py → readers/markdown_reader.py} +1 -1
- ara_cli/file_loaders/readers/odt_reader.py +59 -0
- ara_cli/file_loaders/readers/pdf_reader.py +54 -0
- ara_cli/file_loaders/readers/pptx_reader.py +104 -0
- ara_cli/file_loaders/tools/__init__.py +0 -0
- ara_cli/output_suppressor.py +53 -0
- ara_cli/prompt_handler.py +123 -17
- ara_cli/tag_extractor.py +8 -7
- ara_cli/version.py +1 -1
- {ara_cli-0.1.13.3.dist-info → ara_cli-0.1.14.0.dist-info}/METADATA +18 -12
- {ara_cli-0.1.13.3.dist-info → ara_cli-0.1.14.0.dist-info}/RECORD +58 -45
- {ara_cli-0.1.13.3.dist-info → ara_cli-0.1.14.0.dist-info}/WHEEL +1 -1
- tests/test_artefact_converter.py +1 -46
- tests/test_artefact_lister.py +11 -8
- tests/test_chat.py +4 -4
- tests/test_chat_givens_images.py +1 -1
- tests/test_children_contribution_updater.py +98 -0
- tests/test_document_loader_office.py +267 -0
- tests/test_prompt_handler.py +416 -214
- tests/test_setup_default_chat_prompt_mode.py +198 -0
- tests/test_tag_extractor.py +95 -49
- ara_cli/file_loaders/document_readers.py +0 -233
- ara_cli/file_loaders/file_loaders.py +0 -123
- ara_cli/file_loaders/text_file_loader.py +0 -187
- /ara_cli/file_loaders/{binary_file_loader.py → loaders/binary_file_loader.py} +0 -0
- /ara_cli/file_loaders/{image_processor.py → tools/image_processor.py} +0 -0
- {ara_cli-0.1.13.3.dist-info → ara_cli-0.1.14.0.dist-info}/entry_points.txt +0 -0
- {ara_cli-0.1.13.3.dist-info → ara_cli-0.1.14.0.dist-info}/top_level.txt +0 -0
ara_cli/__init__.py
CHANGED
ara_cli/ara_command_action.py
CHANGED
|
@@ -23,33 +23,44 @@ def create_action(args):
|
|
|
23
23
|
from ara_cli.artefact_reader import ArtefactReader
|
|
24
24
|
from ara_cli.artefact_fuzzy_search import find_closest_rule
|
|
25
25
|
|
|
26
|
-
check_validity(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
check_validity(
|
|
27
|
+
Classifier.is_valid_classifier(args.classifier),
|
|
28
|
+
"Invalid classifier provided. Please provide a valid classifier.",
|
|
29
|
+
)
|
|
30
|
+
check_validity(
|
|
31
|
+
is_valid_filename(args.parameter),
|
|
32
|
+
"Invalid filename provided. Please provide a valid filename.",
|
|
33
|
+
)
|
|
30
34
|
|
|
31
35
|
def handle_parent_arguments(args):
|
|
32
|
-
parent_classifier =
|
|
33
|
-
args, "parent_classifier") else None
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
rule = args.rule if hasattr(args,
|
|
37
|
-
invalid_classifier_message =
|
|
38
|
-
|
|
36
|
+
parent_classifier = (
|
|
37
|
+
args.parent_classifier if hasattr(args, "parent_classifier") else None
|
|
38
|
+
)
|
|
39
|
+
parent_name = args.parent_name if hasattr(args, "parent_name") else None
|
|
40
|
+
rule = args.rule if hasattr(args, "rule") else None
|
|
41
|
+
invalid_classifier_message = (
|
|
42
|
+
"Invalid parent classifier provided. Please provide a valid classifier"
|
|
43
|
+
)
|
|
44
|
+
invalid_name_message = (
|
|
45
|
+
"Invalid filename provided for parent. Please provide a valid filename."
|
|
46
|
+
)
|
|
39
47
|
if parent_classifier and parent_name and rule:
|
|
40
|
-
check_validity(
|
|
41
|
-
parent_classifier),
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
check_validity(
|
|
49
|
+
Classifier.is_valid_classifier(parent_classifier),
|
|
50
|
+
invalid_classifier_message,
|
|
51
|
+
)
|
|
52
|
+
check_validity(is_valid_filename(parent_name), invalid_name_message)
|
|
53
|
+
parent_artefact = ArtefactReader().read_artefact(
|
|
54
|
+
artefact_name=parent_name, classifier=parent_classifier
|
|
55
|
+
)
|
|
46
56
|
rule = find_closest_rule(parent_artefact, rule)
|
|
47
57
|
return parent_classifier, parent_name, rule
|
|
48
58
|
if parent_classifier and parent_name:
|
|
49
|
-
check_validity(
|
|
50
|
-
parent_classifier),
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
check_validity(
|
|
60
|
+
Classifier.is_valid_classifier(parent_classifier),
|
|
61
|
+
invalid_classifier_message,
|
|
62
|
+
)
|
|
63
|
+
check_validity(is_valid_filename(parent_name), invalid_name_message)
|
|
53
64
|
return parent_classifier, parent_name, rule
|
|
54
65
|
return None, None, None
|
|
55
66
|
|
|
@@ -70,8 +81,9 @@ def create_action(args):
|
|
|
70
81
|
return
|
|
71
82
|
|
|
72
83
|
artefact_creator = ArtefactCreator()
|
|
73
|
-
artefact_creator.run(
|
|
74
|
-
|
|
84
|
+
artefact_creator.run(
|
|
85
|
+
args.parameter, args.classifier, parent_classifier, parent_name, rule
|
|
86
|
+
)
|
|
75
87
|
|
|
76
88
|
|
|
77
89
|
@handle_errors(context="delete action", error_handler=error_handler)
|
|
@@ -88,12 +100,18 @@ def rename_action(args):
|
|
|
88
100
|
from ara_cli.classifier import Classifier
|
|
89
101
|
from ara_cli.filename_validator import is_valid_filename
|
|
90
102
|
|
|
91
|
-
check_validity(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
check_validity(
|
|
96
|
-
args.
|
|
103
|
+
check_validity(
|
|
104
|
+
is_valid_filename(args.parameter),
|
|
105
|
+
"Invalid filename provided. Please provide a valid filename.",
|
|
106
|
+
)
|
|
107
|
+
check_validity(
|
|
108
|
+
Classifier.is_valid_classifier(args.classifier),
|
|
109
|
+
"Invalid classifier provided. Please provide a valid classifier.",
|
|
110
|
+
)
|
|
111
|
+
check_validity(
|
|
112
|
+
is_valid_filename(args.aspect),
|
|
113
|
+
"Invalid new filename provided. Please provide a valid filename.",
|
|
114
|
+
)
|
|
97
115
|
|
|
98
116
|
artefact_renamer = ArtefactRenamer()
|
|
99
117
|
artefact_renamer.rename(args.parameter, args.aspect, args.classifier)
|
|
@@ -124,7 +142,7 @@ def list_action(args):
|
|
|
124
142
|
include_extension=args.include_extension,
|
|
125
143
|
exclude_extension=args.exclude_extension,
|
|
126
144
|
include_tags=args.include_tags,
|
|
127
|
-
exclude_tags=args.exclude_tags
|
|
145
|
+
exclude_tags=args.exclude_tags,
|
|
128
146
|
)
|
|
129
147
|
|
|
130
148
|
# Map flags to their corresponding methods
|
|
@@ -165,7 +183,7 @@ def list_tags_action(args):
|
|
|
165
183
|
tag_extractor = TagExtractor()
|
|
166
184
|
tag_groups = tag_extractor.extract_tags(
|
|
167
185
|
filtered_extra_column=getattr(args, "filtered_extra_column", False),
|
|
168
|
-
list_filter=list_filter
|
|
186
|
+
list_filter=list_filter,
|
|
169
187
|
)
|
|
170
188
|
|
|
171
189
|
if args.json:
|
|
@@ -190,71 +208,91 @@ def prompt_action(args):
|
|
|
190
208
|
from ara_cli.classifier import Classifier
|
|
191
209
|
from ara_cli.filename_validator import is_valid_filename
|
|
192
210
|
|
|
193
|
-
check_validity(
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
211
|
+
check_validity(
|
|
212
|
+
Classifier.is_valid_classifier(args.classifier),
|
|
213
|
+
"Invalid classifier provided. Please provide a valid classifier.",
|
|
214
|
+
)
|
|
215
|
+
check_validity(
|
|
216
|
+
is_valid_filename(args.parameter),
|
|
217
|
+
"Invalid filename provided. Please provide a valid filename.",
|
|
218
|
+
)
|
|
197
219
|
|
|
198
220
|
classifier = args.classifier
|
|
199
221
|
param = args.parameter
|
|
200
222
|
init = args.steps
|
|
201
|
-
write = getattr(args,
|
|
223
|
+
write = getattr(args, "write", False)
|
|
202
224
|
|
|
203
225
|
def handle_init():
|
|
204
226
|
from ara_cli.prompt_handler import initialize_prompt_templates
|
|
227
|
+
|
|
205
228
|
initialize_prompt_templates(classifier, param)
|
|
206
229
|
|
|
207
230
|
def handle_init_rag():
|
|
208
231
|
from ara_cli.prompt_handler import initialize_prompt_templates
|
|
209
232
|
from ara_cli.prompt_rag import search_and_add_relevant_files_to_prompt_givens
|
|
233
|
+
|
|
210
234
|
initialize_prompt_templates(classifier, param)
|
|
211
235
|
search_and_add_relevant_files_to_prompt_givens(classifier, param)
|
|
212
236
|
|
|
213
237
|
def handle_load():
|
|
214
238
|
from ara_cli.prompt_handler import load_selected_prompt_templates
|
|
239
|
+
|
|
215
240
|
load_selected_prompt_templates(classifier, param)
|
|
216
241
|
|
|
217
242
|
def handle_send():
|
|
218
243
|
from ara_cli.prompt_handler import create_and_send_custom_prompt
|
|
244
|
+
|
|
219
245
|
create_and_send_custom_prompt(classifier, param)
|
|
220
246
|
|
|
221
247
|
def handle_load_and_send():
|
|
222
|
-
from ara_cli.prompt_handler import
|
|
248
|
+
from ara_cli.prompt_handler import (
|
|
249
|
+
load_selected_prompt_templates,
|
|
250
|
+
create_and_send_custom_prompt,
|
|
251
|
+
)
|
|
252
|
+
|
|
223
253
|
load_selected_prompt_templates(classifier, param)
|
|
224
254
|
create_and_send_custom_prompt(classifier, param)
|
|
225
255
|
|
|
226
256
|
def handle_extract():
|
|
227
257
|
from ara_cli.prompt_extractor import extract_and_save_prompt_results
|
|
228
258
|
from ara_cli.update_config_prompt import update_artefact_config_prompt_files
|
|
259
|
+
|
|
229
260
|
extract_and_save_prompt_results(classifier, param, write=write)
|
|
230
261
|
print(f"automatic update after extract")
|
|
231
|
-
update_artefact_config_prompt_files(
|
|
232
|
-
classifier, param, automatic_update=True)
|
|
262
|
+
update_artefact_config_prompt_files(classifier, param, automatic_update=True)
|
|
233
263
|
|
|
234
264
|
def handle_chat():
|
|
235
265
|
from ara_cli.prompt_chat import initialize_prompt_chat_mode
|
|
266
|
+
|
|
236
267
|
chat_name = args.chat_name
|
|
237
268
|
reset = args.reset
|
|
238
269
|
output_mode = args.output_mode
|
|
239
270
|
append_strings = args.append
|
|
240
271
|
restricted = args.restricted
|
|
241
|
-
initialize_prompt_chat_mode(
|
|
242
|
-
|
|
272
|
+
initialize_prompt_chat_mode(
|
|
273
|
+
classifier,
|
|
274
|
+
param,
|
|
275
|
+
chat_name,
|
|
276
|
+
reset=reset,
|
|
277
|
+
output_mode=output_mode,
|
|
278
|
+
append_strings=append_strings,
|
|
279
|
+
restricted=restricted,
|
|
280
|
+
)
|
|
243
281
|
|
|
244
282
|
def handle_update():
|
|
245
283
|
from ara_cli.update_config_prompt import update_artefact_config_prompt_files
|
|
246
|
-
|
|
247
|
-
|
|
284
|
+
|
|
285
|
+
update_artefact_config_prompt_files(classifier, param, automatic_update=True)
|
|
248
286
|
|
|
249
287
|
command_dispatcher = {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
288
|
+
"init": handle_init,
|
|
289
|
+
"init-rag": handle_init_rag,
|
|
290
|
+
"load": handle_load,
|
|
291
|
+
"send": handle_send,
|
|
292
|
+
"load-and-send": handle_load_and_send,
|
|
293
|
+
"extract": handle_extract,
|
|
294
|
+
"chat": handle_chat,
|
|
295
|
+
"update": handle_update,
|
|
258
296
|
}
|
|
259
297
|
|
|
260
298
|
if init in command_dispatcher:
|
|
@@ -279,8 +317,11 @@ def chat_action(args):
|
|
|
279
317
|
chat_file_path = join(cwd, chat_name)
|
|
280
318
|
|
|
281
319
|
with suppress_stdout(output_mode):
|
|
282
|
-
chat =
|
|
283
|
-
chat_file_path, reset=reset
|
|
320
|
+
chat = (
|
|
321
|
+
Chat(chat_file_path, reset=reset)
|
|
322
|
+
if not restricted
|
|
323
|
+
else Chat(chat_file_path, reset=reset, enable_commands=whitelisted_commands)
|
|
324
|
+
)
|
|
284
325
|
|
|
285
326
|
if append_strings:
|
|
286
327
|
chat.append_strings(append_strings)
|
|
@@ -324,21 +365,22 @@ def load_action(args):
|
|
|
324
365
|
default_patterns = {
|
|
325
366
|
"rules": "*.rules.md",
|
|
326
367
|
"intention": "*.intention.md",
|
|
327
|
-
"commands": "*.commands.md"
|
|
368
|
+
"commands": "*.commands.md",
|
|
328
369
|
}
|
|
329
370
|
|
|
330
371
|
default_pattern = default_patterns.get(template_type)
|
|
331
372
|
|
|
332
373
|
if not template_name and not default_pattern:
|
|
333
374
|
raise AraError(
|
|
334
|
-
f"A template name is required for template type '{template_type}'."
|
|
375
|
+
f"A template name is required for template type '{template_type}'."
|
|
376
|
+
)
|
|
335
377
|
|
|
336
378
|
loader = TemplateLoader() # No chat instance for CLI context
|
|
337
379
|
success = loader.load_template(
|
|
338
380
|
template_name=template_name,
|
|
339
381
|
template_type=template_type,
|
|
340
382
|
chat_file_path=chat_file_path,
|
|
341
|
-
default_pattern=default_pattern
|
|
383
|
+
default_pattern=default_pattern,
|
|
342
384
|
)
|
|
343
385
|
|
|
344
386
|
if not success:
|
|
@@ -350,8 +392,10 @@ def template_action(args):
|
|
|
350
392
|
from ara_cli.classifier import Classifier
|
|
351
393
|
from ara_cli.template_manager import TemplatePathManager
|
|
352
394
|
|
|
353
|
-
check_validity(
|
|
354
|
-
|
|
395
|
+
check_validity(
|
|
396
|
+
Classifier.is_valid_classifier(args.classifier),
|
|
397
|
+
"Invalid classifier provided. Please provide a valid classifier.",
|
|
398
|
+
)
|
|
355
399
|
|
|
356
400
|
template_manager = TemplatePathManager()
|
|
357
401
|
content = template_manager.get_template_content(args.classifier)
|
|
@@ -372,11 +416,9 @@ def fetch_templates_action(args):
|
|
|
372
416
|
|
|
373
417
|
subdirs = ["commands", "rules", "intentions", "blueprints"]
|
|
374
418
|
|
|
375
|
-
os.makedirs(join(prompt_templates_dir,
|
|
376
|
-
"global-prompt-modules"), exist_ok=True)
|
|
419
|
+
os.makedirs(join(prompt_templates_dir, "global-prompt-modules"), exist_ok=True)
|
|
377
420
|
for subdir in subdirs:
|
|
378
|
-
target_dir = join(prompt_templates_dir,
|
|
379
|
-
"global-prompt-modules", subdir)
|
|
421
|
+
target_dir = join(prompt_templates_dir, "global-prompt-modules", subdir)
|
|
380
422
|
source_dir = join(global_prompt_templates_path, subdir)
|
|
381
423
|
os.makedirs(target_dir, exist_ok=True)
|
|
382
424
|
for item in os.listdir(source_dir):
|
|
@@ -386,7 +428,8 @@ def fetch_templates_action(args):
|
|
|
386
428
|
|
|
387
429
|
custom_prompt_templates_subdir = config.custom_prompt_templates_subdir
|
|
388
430
|
local_prompt_modules_dir = join(
|
|
389
|
-
prompt_templates_dir, custom_prompt_templates_subdir
|
|
431
|
+
prompt_templates_dir, custom_prompt_templates_subdir
|
|
432
|
+
)
|
|
390
433
|
os.makedirs(local_prompt_modules_dir, exist_ok=True)
|
|
391
434
|
for subdir in subdirs:
|
|
392
435
|
os.makedirs(join(local_prompt_modules_dir, subdir), exist_ok=True)
|
|
@@ -407,14 +450,14 @@ def read_action(args):
|
|
|
407
450
|
include_extension=args.include_extension,
|
|
408
451
|
exclude_extension=args.exclude_extension,
|
|
409
452
|
include_tags=args.include_tags,
|
|
410
|
-
exclude_tags=args.exclude_tags
|
|
453
|
+
exclude_tags=args.exclude_tags,
|
|
411
454
|
)
|
|
412
455
|
|
|
413
456
|
command = ReadCommand(
|
|
414
457
|
classifier=classifier,
|
|
415
458
|
artefact_name=artefact_name,
|
|
416
459
|
read_mode=read_mode,
|
|
417
|
-
list_filter=list_filter
|
|
460
|
+
list_filter=list_filter,
|
|
418
461
|
)
|
|
419
462
|
|
|
420
463
|
command.execute()
|
|
@@ -432,7 +475,7 @@ def reconnect_action(args):
|
|
|
432
475
|
artefact_name = args.parameter
|
|
433
476
|
parent_classifier = args.parent_classifier
|
|
434
477
|
parent_name = args.parent_name
|
|
435
|
-
rule = args.rule if hasattr(args,
|
|
478
|
+
rule = args.rule if hasattr(args, "rule") else None
|
|
436
479
|
|
|
437
480
|
read_error_message = f"Could not connect {classifier} '{artefact_name}' to {parent_classifier} '{parent_name}'"
|
|
438
481
|
|
|
@@ -441,27 +484,27 @@ def reconnect_action(args):
|
|
|
441
484
|
file_classifier = FileClassifier(os)
|
|
442
485
|
classified_file_info = file_classifier.classify_files()
|
|
443
486
|
|
|
444
|
-
|
|
487
|
+
reader = ArtefactReader()
|
|
488
|
+
artefact = reader.read_artefact(
|
|
445
489
|
artefact_name=artefact_name,
|
|
446
490
|
classifier=classifier,
|
|
447
|
-
classified_file_info=classified_file_info
|
|
491
|
+
classified_file_info=classified_file_info,
|
|
448
492
|
)
|
|
449
493
|
|
|
450
494
|
if not artefact:
|
|
451
495
|
raise AraError(read_error_message)
|
|
452
496
|
|
|
453
|
-
parent =
|
|
497
|
+
parent = reader.read_artefact(
|
|
454
498
|
artefact_name=parent_name,
|
|
455
499
|
classifier=parent_classifier,
|
|
456
|
-
classified_file_info=classified_file_info
|
|
500
|
+
classified_file_info=classified_file_info,
|
|
457
501
|
)
|
|
458
502
|
|
|
459
503
|
if not parent:
|
|
460
504
|
raise AraError(read_error_message)
|
|
461
505
|
|
|
462
506
|
contribution = Contribution(
|
|
463
|
-
artefact_name=parent.title,
|
|
464
|
-
classifier=parent.artefact_type
|
|
507
|
+
artefact_name=parent.title, classifier=parent.artefact_type
|
|
465
508
|
)
|
|
466
509
|
|
|
467
510
|
if rule:
|
|
@@ -470,7 +513,7 @@ def reconnect_action(args):
|
|
|
470
513
|
feedback_message += f" using rule '{closest_rule}'"
|
|
471
514
|
|
|
472
515
|
artefact.contribution = contribution
|
|
473
|
-
with open(artefact.file_path,
|
|
516
|
+
with open(artefact.file_path, "w", encoding="utf-8") as file:
|
|
474
517
|
artefact_content = artefact.serialize()
|
|
475
518
|
file.write(artefact_content)
|
|
476
519
|
|
|
@@ -489,18 +532,20 @@ def read_status_action(args):
|
|
|
489
532
|
artefact_info = file_classifier.classify_files()
|
|
490
533
|
artefact_info_dicts = artefact_info.get(classifier, [])
|
|
491
534
|
|
|
492
|
-
all_artefact_names = [
|
|
493
|
-
|
|
535
|
+
all_artefact_names = [
|
|
536
|
+
artefact_info["title"] for artefact_info in artefact_info_dicts
|
|
537
|
+
]
|
|
494
538
|
if artefact_name not in all_artefact_names:
|
|
495
539
|
suggest_close_name_matches(
|
|
496
|
-
artefact_name, all_artefact_names, report_as_error=True
|
|
540
|
+
artefact_name, all_artefact_names, report_as_error=True
|
|
541
|
+
)
|
|
497
542
|
return
|
|
498
543
|
|
|
499
|
-
artefact_info = next(
|
|
500
|
-
lambda x: x["title"] == artefact_name, artefact_info_dicts
|
|
501
|
-
)
|
|
544
|
+
artefact_info = next(
|
|
545
|
+
filter(lambda x: x["title"] == artefact_name, artefact_info_dicts)
|
|
546
|
+
)
|
|
502
547
|
|
|
503
|
-
with open(artefact_info["file_path"],
|
|
548
|
+
with open(artefact_info["file_path"], "r", encoding="utf-8") as file:
|
|
504
549
|
content = file.read()
|
|
505
550
|
artefact = artefact_from_content(content)
|
|
506
551
|
|
|
@@ -524,18 +569,20 @@ def read_user_action(args):
|
|
|
524
569
|
artefact_info = file_classifier.classify_files()
|
|
525
570
|
artefact_info_dicts = artefact_info.get(classifier, [])
|
|
526
571
|
|
|
527
|
-
all_artefact_names = [
|
|
528
|
-
|
|
572
|
+
all_artefact_names = [
|
|
573
|
+
artefact_info["title"] for artefact_info in artefact_info_dicts
|
|
574
|
+
]
|
|
529
575
|
if artefact_name not in all_artefact_names:
|
|
530
576
|
suggest_close_name_matches(
|
|
531
|
-
artefact_name, all_artefact_names, report_as_error=True
|
|
577
|
+
artefact_name, all_artefact_names, report_as_error=True
|
|
578
|
+
)
|
|
532
579
|
return
|
|
533
580
|
|
|
534
|
-
artefact_info = next(
|
|
535
|
-
lambda x: x["title"] == artefact_name, artefact_info_dicts
|
|
536
|
-
)
|
|
581
|
+
artefact_info = next(
|
|
582
|
+
filter(lambda x: x["title"] == artefact_name, artefact_info_dicts)
|
|
583
|
+
)
|
|
537
584
|
|
|
538
|
-
with open(artefact_info["file_path"],
|
|
585
|
+
with open(artefact_info["file_path"], "r", encoding="utf-8") as file:
|
|
539
586
|
content = file.read()
|
|
540
587
|
artefact = artefact_from_content(content)
|
|
541
588
|
|
|
@@ -560,38 +607,40 @@ def set_status_action(args):
|
|
|
560
607
|
artefact_name = args.parameter
|
|
561
608
|
new_status = args.new_status
|
|
562
609
|
|
|
563
|
-
if new_status.startswith(
|
|
564
|
-
new_status = new_status.lstrip(
|
|
610
|
+
if new_status.startswith("@"):
|
|
611
|
+
new_status = new_status.lstrip("@")
|
|
565
612
|
|
|
566
|
-
check_validity(
|
|
567
|
-
|
|
613
|
+
check_validity(
|
|
614
|
+
new_status in status_tags,
|
|
615
|
+
"Invalid status provided. Please provide a valid status.",
|
|
616
|
+
)
|
|
568
617
|
|
|
569
618
|
file_classifier = FileClassifier(os)
|
|
570
619
|
classified_artefacts_info = file_classifier.classify_files()
|
|
571
620
|
classified_artefact_dict = classified_artefacts_info.get(classifier, [])
|
|
572
|
-
all_artefact_names = [
|
|
573
|
-
|
|
621
|
+
all_artefact_names = [
|
|
622
|
+
artefact_info["title"] for artefact_info in classified_artefact_dict
|
|
623
|
+
]
|
|
574
624
|
|
|
575
625
|
if artefact_name not in all_artefact_names:
|
|
576
626
|
suggest_close_name_matches(artefact_name, all_artefact_names)
|
|
577
627
|
return
|
|
578
628
|
|
|
579
|
-
artefact_info = next(
|
|
580
|
-
lambda x: x["title"] == artefact_name, classified_artefact_dict
|
|
581
|
-
)
|
|
629
|
+
artefact_info = next(
|
|
630
|
+
filter(lambda x: x["title"] == artefact_name, classified_artefact_dict)
|
|
631
|
+
)
|
|
582
632
|
|
|
583
|
-
with open(artefact_info["file_path"],
|
|
633
|
+
with open(artefact_info["file_path"], "r", encoding="utf-8") as file:
|
|
584
634
|
content = file.read()
|
|
585
635
|
artefact = artefact_from_content(content)
|
|
586
636
|
|
|
587
637
|
artefact.status = new_status
|
|
588
638
|
|
|
589
639
|
serialized_content = artefact.serialize()
|
|
590
|
-
with open(f"{artefact_info['file_path']}",
|
|
640
|
+
with open(f"{artefact_info['file_path']}", "w", encoding="utf-8") as file:
|
|
591
641
|
file.write(serialized_content)
|
|
592
642
|
|
|
593
|
-
print(
|
|
594
|
-
f"Status of task '{artefact_name}' has been updated to '{new_status}'.")
|
|
643
|
+
print(f"Status of task '{artefact_name}' has been updated to '{new_status}'.")
|
|
595
644
|
|
|
596
645
|
|
|
597
646
|
@handle_errors(context="set-user action", error_handler=error_handler)
|
|
@@ -603,24 +652,25 @@ def set_user_action(args):
|
|
|
603
652
|
artefact_name = args.parameter
|
|
604
653
|
new_user = args.new_user
|
|
605
654
|
|
|
606
|
-
if new_user.startswith(
|
|
607
|
-
new_user = new_user.lstrip(
|
|
655
|
+
if new_user.startswith("@"):
|
|
656
|
+
new_user = new_user.lstrip("@")
|
|
608
657
|
|
|
609
658
|
file_classifier = FileClassifier(os)
|
|
610
659
|
classified_artefacts_info = file_classifier.classify_files()
|
|
611
660
|
classified_artefact_dict = classified_artefacts_info.get(classifier, [])
|
|
612
|
-
all_artefact_names = [
|
|
613
|
-
|
|
661
|
+
all_artefact_names = [
|
|
662
|
+
artefact_info["title"] for artefact_info in classified_artefact_dict
|
|
663
|
+
]
|
|
614
664
|
|
|
615
665
|
if artefact_name not in all_artefact_names:
|
|
616
666
|
suggest_close_name_matches(artefact_name, all_artefact_names)
|
|
617
667
|
return
|
|
618
668
|
|
|
619
|
-
artefact_info = next(
|
|
620
|
-
lambda x: x["title"] == artefact_name, classified_artefact_dict
|
|
621
|
-
)
|
|
669
|
+
artefact_info = next(
|
|
670
|
+
filter(lambda x: x["title"] == artefact_name, classified_artefact_dict)
|
|
671
|
+
)
|
|
622
672
|
|
|
623
|
-
with open(artefact_info["file_path"],
|
|
673
|
+
with open(artefact_info["file_path"], "r", encoding="utf-8") as file:
|
|
624
674
|
content = file.read()
|
|
625
675
|
artefact = artefact_from_content(content)
|
|
626
676
|
|
|
@@ -628,7 +678,7 @@ def set_user_action(args):
|
|
|
628
678
|
|
|
629
679
|
serialized_content = artefact.serialize()
|
|
630
680
|
|
|
631
|
-
with open(artefact_info["file_path"],
|
|
681
|
+
with open(artefact_info["file_path"], "w", encoding="utf-8") as file:
|
|
632
682
|
file.write(serialized_content)
|
|
633
683
|
|
|
634
684
|
print(f"User of task '{artefact_name}' has been updated to '{new_user}'.")
|
|
@@ -692,7 +742,7 @@ def autofix_action(args):
|
|
|
692
742
|
single_pass=args.single_pass,
|
|
693
743
|
deterministic=run_deterministic,
|
|
694
744
|
non_deterministic=run_non_deterministic,
|
|
695
|
-
classified_artefact_info=classified_artefact_info
|
|
745
|
+
classified_artefact_info=classified_artefact_info,
|
|
696
746
|
)
|
|
697
747
|
|
|
698
748
|
print("\nAutofix process completed. Please review the changes.")
|
|
@@ -704,11 +754,11 @@ def extract_action(args):
|
|
|
704
754
|
|
|
705
755
|
filename = args.filename
|
|
706
756
|
force = args.force
|
|
707
|
-
write = getattr(args,
|
|
757
|
+
write = getattr(args, "write", False)
|
|
708
758
|
command = ExtractCommand(
|
|
709
759
|
file_name=filename,
|
|
710
760
|
force=force,
|
|
711
761
|
write=write,
|
|
712
|
-
output=lambda msg: print(msg, file=sys.stdout)
|
|
762
|
+
output=lambda msg: print(msg, file=sys.stdout),
|
|
713
763
|
)
|
|
714
764
|
command.execute()
|
ara_cli/ara_config.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import typer
|
|
2
|
+
from typing import Optional
|
|
2
3
|
|
|
3
4
|
from ara_cli import error_handler
|
|
4
5
|
from ara_cli.completers import DynamicCompleters
|
|
@@ -28,16 +29,79 @@ def register(app: typer.Typer):
|
|
|
28
29
|
override: bool = typer.Option(
|
|
29
30
|
False, "--override", help="Override existing artefact if it exists"
|
|
30
31
|
),
|
|
32
|
+
force: bool = typer.Option(
|
|
33
|
+
False,
|
|
34
|
+
"-f",
|
|
35
|
+
"--force",
|
|
36
|
+
help="When converting to task/issue, automatically clear children's contribution fields",
|
|
37
|
+
),
|
|
38
|
+
json_output: bool = typer.Option(
|
|
39
|
+
False,
|
|
40
|
+
"-j",
|
|
41
|
+
"--json",
|
|
42
|
+
help="Output results as JSON (for API/non-interactive mode)",
|
|
43
|
+
),
|
|
44
|
+
children_action: Optional[str] = typer.Option(
|
|
45
|
+
None,
|
|
46
|
+
"--children-action",
|
|
47
|
+
help="Non-interactive mode: Action for children (cancel/clear/reassign)",
|
|
48
|
+
),
|
|
49
|
+
new_parent_classifier: Optional[str] = typer.Option(
|
|
50
|
+
None,
|
|
51
|
+
"--new-parent-classifier",
|
|
52
|
+
help="For reassign action: classifier of the new parent artefact",
|
|
53
|
+
autocompletion=DynamicCompleters.create_classifier_completer(),
|
|
54
|
+
),
|
|
55
|
+
new_parent_name: Optional[str] = typer.Option(
|
|
56
|
+
None,
|
|
57
|
+
"--new-parent-name",
|
|
58
|
+
help="For reassign action: name of the new parent artefact",
|
|
59
|
+
),
|
|
60
|
+
preview: bool = typer.Option(
|
|
61
|
+
False,
|
|
62
|
+
"--preview",
|
|
63
|
+
help="Preview children info without converting (returns JSON)",
|
|
64
|
+
),
|
|
31
65
|
):
|
|
32
66
|
"""
|
|
33
67
|
Convert an existing artefact from one classifier to another.
|
|
68
|
+
|
|
69
|
+
For API/non-interactive mode, use --json and --children-action options.
|
|
70
|
+
Use --preview to get children information without performing conversion.
|
|
34
71
|
"""
|
|
35
72
|
try:
|
|
36
73
|
from ara_cli.artefact_converter import AraArtefactConverter
|
|
74
|
+
from ara_cli.children_contribution_updater import (
|
|
75
|
+
ChildrenContributionUpdater,
|
|
76
|
+
)
|
|
77
|
+
import json
|
|
78
|
+
|
|
79
|
+
# Preview mode: return children info as JSON
|
|
80
|
+
if preview:
|
|
81
|
+
updater = ChildrenContributionUpdater()
|
|
82
|
+
info = updater.get_children_info(
|
|
83
|
+
artefact_name, old_classifier, new_classifier
|
|
84
|
+
)
|
|
85
|
+
print(json.dumps(info, indent=2))
|
|
86
|
+
return
|
|
37
87
|
|
|
38
88
|
converter = AraArtefactConverter()
|
|
39
89
|
converter.convert(
|
|
40
|
-
old_classifier,
|
|
90
|
+
old_classifier,
|
|
91
|
+
artefact_name,
|
|
92
|
+
new_classifier,
|
|
93
|
+
merge,
|
|
94
|
+
override,
|
|
95
|
+
force,
|
|
96
|
+
children_action=children_action,
|
|
97
|
+
new_parent_classifier=new_parent_classifier,
|
|
98
|
+
new_parent_name=new_parent_name,
|
|
99
|
+
json_output=json_output,
|
|
41
100
|
)
|
|
42
101
|
except Exception as e:
|
|
43
|
-
|
|
102
|
+
if json_output:
|
|
103
|
+
import json
|
|
104
|
+
|
|
105
|
+
print(json.dumps({"status": "error", "message": str(e)}))
|
|
106
|
+
else:
|
|
107
|
+
error_handler.handle_error(e)
|