ara-cli 0.1.9.69__py3-none-any.whl → 0.1.10.8__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.

Files changed (150) hide show
  1. ara_cli/__init__.py +18 -2
  2. ara_cli/__main__.py +248 -62
  3. ara_cli/ara_command_action.py +155 -86
  4. ara_cli/ara_config.py +226 -80
  5. ara_cli/ara_subcommands/__init__.py +0 -0
  6. ara_cli/ara_subcommands/autofix.py +26 -0
  7. ara_cli/ara_subcommands/chat.py +27 -0
  8. ara_cli/ara_subcommands/classifier_directory.py +16 -0
  9. ara_cli/ara_subcommands/common.py +100 -0
  10. ara_cli/ara_subcommands/create.py +75 -0
  11. ara_cli/ara_subcommands/delete.py +22 -0
  12. ara_cli/ara_subcommands/extract.py +22 -0
  13. ara_cli/ara_subcommands/fetch_templates.py +14 -0
  14. ara_cli/ara_subcommands/list.py +65 -0
  15. ara_cli/ara_subcommands/list_tags.py +25 -0
  16. ara_cli/ara_subcommands/load.py +48 -0
  17. ara_cli/ara_subcommands/prompt.py +136 -0
  18. ara_cli/ara_subcommands/read.py +47 -0
  19. ara_cli/ara_subcommands/read_status.py +20 -0
  20. ara_cli/ara_subcommands/read_user.py +20 -0
  21. ara_cli/ara_subcommands/reconnect.py +27 -0
  22. ara_cli/ara_subcommands/rename.py +22 -0
  23. ara_cli/ara_subcommands/scan.py +14 -0
  24. ara_cli/ara_subcommands/set_status.py +22 -0
  25. ara_cli/ara_subcommands/set_user.py +22 -0
  26. ara_cli/ara_subcommands/template.py +16 -0
  27. ara_cli/artefact_autofix.py +649 -68
  28. ara_cli/artefact_creator.py +8 -11
  29. ara_cli/artefact_deleter.py +2 -4
  30. ara_cli/artefact_fuzzy_search.py +22 -10
  31. ara_cli/artefact_link_updater.py +4 -4
  32. ara_cli/artefact_lister.py +29 -55
  33. ara_cli/artefact_models/artefact_data_retrieval.py +23 -0
  34. ara_cli/artefact_models/artefact_load.py +11 -3
  35. ara_cli/artefact_models/artefact_model.py +146 -39
  36. ara_cli/artefact_models/artefact_templates.py +70 -44
  37. ara_cli/artefact_models/businessgoal_artefact_model.py +23 -25
  38. ara_cli/artefact_models/epic_artefact_model.py +34 -26
  39. ara_cli/artefact_models/feature_artefact_model.py +203 -64
  40. ara_cli/artefact_models/keyfeature_artefact_model.py +21 -24
  41. ara_cli/artefact_models/serialize_helper.py +1 -1
  42. ara_cli/artefact_models/task_artefact_model.py +83 -15
  43. ara_cli/artefact_models/userstory_artefact_model.py +37 -27
  44. ara_cli/artefact_models/vision_artefact_model.py +23 -42
  45. ara_cli/artefact_reader.py +92 -91
  46. ara_cli/artefact_renamer.py +8 -4
  47. ara_cli/artefact_scan.py +66 -3
  48. ara_cli/chat.py +622 -162
  49. ara_cli/chat_agent/__init__.py +0 -0
  50. ara_cli/chat_agent/agent_communicator.py +62 -0
  51. ara_cli/chat_agent/agent_process_manager.py +211 -0
  52. ara_cli/chat_agent/agent_status_manager.py +73 -0
  53. ara_cli/chat_agent/agent_workspace_manager.py +76 -0
  54. ara_cli/commands/__init__.py +0 -0
  55. ara_cli/commands/command.py +7 -0
  56. ara_cli/commands/extract_command.py +15 -0
  57. ara_cli/commands/load_command.py +65 -0
  58. ara_cli/commands/load_image_command.py +34 -0
  59. ara_cli/commands/read_command.py +117 -0
  60. ara_cli/completers.py +144 -0
  61. ara_cli/directory_navigator.py +37 -4
  62. ara_cli/error_handler.py +134 -0
  63. ara_cli/file_classifier.py +6 -5
  64. ara_cli/file_lister.py +1 -1
  65. ara_cli/file_loaders/__init__.py +0 -0
  66. ara_cli/file_loaders/binary_file_loader.py +33 -0
  67. ara_cli/file_loaders/document_file_loader.py +34 -0
  68. ara_cli/file_loaders/document_reader.py +245 -0
  69. ara_cli/file_loaders/document_readers.py +233 -0
  70. ara_cli/file_loaders/file_loader.py +50 -0
  71. ara_cli/file_loaders/file_loaders.py +123 -0
  72. ara_cli/file_loaders/image_processor.py +89 -0
  73. ara_cli/file_loaders/markdown_reader.py +75 -0
  74. ara_cli/file_loaders/text_file_loader.py +187 -0
  75. ara_cli/global_file_lister.py +51 -0
  76. ara_cli/list_filter.py +1 -1
  77. ara_cli/output_suppressor.py +1 -1
  78. ara_cli/prompt_extractor.py +215 -88
  79. ara_cli/prompt_handler.py +521 -134
  80. ara_cli/prompt_rag.py +2 -2
  81. ara_cli/tag_extractor.py +83 -38
  82. ara_cli/template_loader.py +245 -0
  83. ara_cli/template_manager.py +18 -13
  84. ara_cli/templates/prompt-modules/commands/empty.commands.md +2 -12
  85. ara_cli/templates/prompt-modules/commands/extract_general.commands.md +12 -0
  86. ara_cli/templates/prompt-modules/commands/extract_markdown.commands.md +11 -0
  87. ara_cli/templates/prompt-modules/commands/extract_python.commands.md +13 -0
  88. ara_cli/templates/prompt-modules/commands/feature_add_or_modifiy_specified_behavior.commands.md +36 -0
  89. ara_cli/templates/prompt-modules/commands/feature_generate_initial_specified_bevahior.commands.md +53 -0
  90. ara_cli/templates/prompt-modules/commands/prompt_template_tech_stack_transformer.commands.md +95 -0
  91. ara_cli/templates/prompt-modules/commands/python_bug_fixing_code.commands.md +34 -0
  92. ara_cli/templates/prompt-modules/commands/python_generate_code.commands.md +27 -0
  93. ara_cli/templates/prompt-modules/commands/python_refactoring_code.commands.md +39 -0
  94. ara_cli/templates/prompt-modules/commands/python_step_definitions_generation_and_fixing.commands.md +40 -0
  95. ara_cli/templates/prompt-modules/commands/python_unittest_generation_and_fixing.commands.md +48 -0
  96. ara_cli/update_config_prompt.py +9 -3
  97. ara_cli/version.py +1 -1
  98. ara_cli-0.1.10.8.dist-info/METADATA +241 -0
  99. ara_cli-0.1.10.8.dist-info/RECORD +193 -0
  100. tests/test_ara_command_action.py +73 -59
  101. tests/test_ara_config.py +341 -36
  102. tests/test_artefact_autofix.py +1060 -0
  103. tests/test_artefact_link_updater.py +3 -3
  104. tests/test_artefact_lister.py +52 -132
  105. tests/test_artefact_renamer.py +2 -2
  106. tests/test_artefact_scan.py +327 -33
  107. tests/test_chat.py +2063 -498
  108. tests/test_file_classifier.py +24 -1
  109. tests/test_file_creator.py +3 -5
  110. tests/test_file_lister.py +1 -1
  111. tests/test_global_file_lister.py +131 -0
  112. tests/test_list_filter.py +2 -2
  113. tests/test_prompt_handler.py +746 -0
  114. tests/test_tag_extractor.py +19 -13
  115. tests/test_template_loader.py +192 -0
  116. tests/test_template_manager.py +5 -4
  117. tests/test_update_config_prompt.py +2 -2
  118. ara_cli/ara_command_parser.py +0 -327
  119. ara_cli/templates/prompt-modules/blueprints/complete_pytest_unittest.blueprint.md +0 -27
  120. ara_cli/templates/prompt-modules/blueprints/task_todo_list_implement_feature_BDD_way.blueprint.md +0 -30
  121. ara_cli/templates/prompt-modules/commands/artefact_classification.commands.md +0 -9
  122. ara_cli/templates/prompt-modules/commands/artefact_extension.commands.md +0 -17
  123. ara_cli/templates/prompt-modules/commands/artefact_formulation.commands.md +0 -14
  124. ara_cli/templates/prompt-modules/commands/behave_step_generation.commands.md +0 -102
  125. ara_cli/templates/prompt-modules/commands/code_generation_complex.commands.md +0 -20
  126. ara_cli/templates/prompt-modules/commands/code_generation_simple.commands.md +0 -13
  127. ara_cli/templates/prompt-modules/commands/error_fixing.commands.md +0 -20
  128. ara_cli/templates/prompt-modules/commands/feature_file_update.commands.md +0 -18
  129. ara_cli/templates/prompt-modules/commands/feature_formulation.commands.md +0 -43
  130. ara_cli/templates/prompt-modules/commands/js_code_generation_simple.commands.md +0 -13
  131. ara_cli/templates/prompt-modules/commands/refactoring.commands.md +0 -15
  132. ara_cli/templates/prompt-modules/commands/refactoring_analysis.commands.md +0 -9
  133. ara_cli/templates/prompt-modules/commands/reverse_engineer_feature_file.commands.md +0 -15
  134. ara_cli/templates/prompt-modules/commands/reverse_engineer_program_flow.commands.md +0 -19
  135. ara_cli/templates/template.businessgoal +0 -10
  136. ara_cli/templates/template.capability +0 -10
  137. ara_cli/templates/template.epic +0 -15
  138. ara_cli/templates/template.example +0 -6
  139. ara_cli/templates/template.feature +0 -26
  140. ara_cli/templates/template.issue +0 -14
  141. ara_cli/templates/template.keyfeature +0 -15
  142. ara_cli/templates/template.task +0 -6
  143. ara_cli/templates/template.userstory +0 -17
  144. ara_cli/templates/template.vision +0 -14
  145. ara_cli-0.1.9.69.dist-info/METADATA +0 -16
  146. ara_cli-0.1.9.69.dist-info/RECORD +0 -158
  147. tests/test_ara_autofix.py +0 -219
  148. {ara_cli-0.1.9.69.dist-info → ara_cli-0.1.10.8.dist-info}/WHEEL +0 -0
  149. {ara_cli-0.1.9.69.dist-info → ara_cli-0.1.10.8.dist-info}/entry_points.txt +0 -0
  150. {ara_cli-0.1.9.69.dist-info → ara_cli-0.1.10.8.dist-info}/top_level.txt +0 -0
@@ -16,7 +16,7 @@ class ArtefactCreator:
16
16
 
17
17
  @lru_cache(maxsize=None)
18
18
  def read_template_content(self, template_file_path):
19
- with open(template_file_path, "r") as template_file:
19
+ with open(template_file_path, "r", encoding="utf-8") as template_file:
20
20
  return template_file.read()
21
21
 
22
22
  def create_artefact_prompt_files(self, dir_path, template_path, classifier):
@@ -38,11 +38,9 @@ class ArtefactCreator:
38
38
  destination = Path(dir_path) / dest_name
39
39
 
40
40
  if not source.exists():
41
- print("[ERROR] Source file does not exist!")
42
41
  raise FileNotFoundError(f"Source file {source} not found!")
43
42
 
44
43
  if not destination.parent.exists():
45
- print("[ERROR] Destination directory does not exist!")
46
44
  raise NotADirectoryError(f"Destination directory {destination.parent} does not exist!")
47
45
 
48
46
  copyfile(source, destination)
@@ -70,9 +68,7 @@ class ArtefactCreator:
70
68
  def validate_template(self, template_path, classifier):
71
69
  template_name = f"template.{classifier}"
72
70
  if not self.template_exists(template_path, template_name):
73
- print(f"Template file '{template_name}' not found in the specified template path.")
74
- return False
75
- return True
71
+ raise FileNotFoundError(f"Template file '{template_name}' not found in the specified template path.")
76
72
 
77
73
  def set_artefact_parent(self, artefact, parent_classifier, parent_file_name) -> Artefact:
78
74
  classified_artefacts = ArtefactReader.read_artefacts()
@@ -94,8 +90,7 @@ class ArtefactCreator:
94
90
  navigator.navigate_to_target()
95
91
 
96
92
  if not Classifier.is_valid_classifier(classifier):
97
- print("Invalid classifier provided. Please provide a valid classifier.")
98
- return
93
+ raise ValueError("Invalid classifier provided. Please provide a valid classifier.")
99
94
 
100
95
  sub_directory = Classifier.get_sub_directory(classifier)
101
96
  file_path = self.file_system.path.join(sub_directory, f"{filename}.{classifier}")
@@ -106,7 +101,7 @@ class ArtefactCreator:
106
101
  if not self.handle_existing_files(file_exists):
107
102
  return
108
103
 
109
- artefact = template_artefact_of_type(classifier, filename)
104
+ artefact = template_artefact_of_type(classifier, filename, True)
110
105
 
111
106
  if parent_classifier and parent_name:
112
107
  artefact.set_contribution(
@@ -114,11 +109,13 @@ class ArtefactCreator:
114
109
  classifier=parent_classifier,
115
110
  rule=rule
116
111
  )
112
+ else:
113
+ artefact.set_contribution(None, None, None)
117
114
 
118
115
  artefact_content = artefact.serialize()
119
116
  rmtree(dir_path, ignore_errors=True)
120
117
  os.makedirs(dir_path, exist_ok=True)
121
- with open(file_path, 'w') as artefact_file:
118
+ with open(file_path, 'w', encoding='utf-8') as artefact_file:
122
119
  artefact_file.write(artefact_content)
123
120
 
124
121
  relative_file_path = os.path.relpath(file_path, original_directory)
@@ -138,7 +135,7 @@ class ArtefactCreator:
138
135
 
139
136
  title = Classifier.get_artefact_title(classifier)
140
137
 
141
- with open(file_path, "r") as file:
138
+ with open(file_path, "r", encoding="utf-8") as file:
142
139
  for line in file:
143
140
  if line.strip().startswith(title):
144
141
  return line.split(':')[1].strip()
@@ -20,16 +20,14 @@ class ArtefactDeleter:
20
20
  self.navigate_to_target()
21
21
 
22
22
  if not Classifier.is_valid_classifier(classifier):
23
- print("Invalid classifier provided. Please provide a valid classifier.")
24
- return
23
+ raise ValueError("Invalid classifier provided. Please provide a valid classifier.")
25
24
 
26
25
  sub_directory = Classifier.get_sub_directory(classifier)
27
26
  file_path = self.file_system.path.join(sub_directory, f"{filename}.{classifier}")
28
27
  dir_path = self.file_system.path.join(sub_directory, f"{filename}.data")
29
28
 
30
29
  if not self.file_system.path.exists(file_path):
31
- print(f"Artefact {file_path} not found.")
32
- return
30
+ raise FileNotFoundError(f"Artefact {file_path} not found.")
33
31
  if not force:
34
32
  user_choice = input(f"Are you sure you want to delete the file {filename} and data directory if existing? (y/N): ")
35
33
 
@@ -1,11 +1,16 @@
1
1
  import difflib
2
2
  from textwrap import indent
3
3
  from typing import Optional
4
+ from . import error_handler
5
+ from ara_cli.error_handler import AraError
4
6
 
5
7
 
6
- def suggest_close_names(artefact_name: str, all_artefact_names: list[str], message: str, cutoff=0.5):
8
+ def suggest_close_names(artefact_name: str, all_artefact_names: list[str], message: str, cutoff=0.5, report_as_error: bool = False):
7
9
  closest_matches = difflib.get_close_matches(artefact_name, all_artefact_names, cutoff=cutoff)
8
- print(message)
10
+ if report_as_error:
11
+ error_handler.report_error(AraError(message))
12
+ else:
13
+ print(message)
9
14
  if not closest_matches:
10
15
  return
11
16
  print("Closest matches:")
@@ -13,32 +18,39 @@ def suggest_close_names(artefact_name: str, all_artefact_names: list[str], messa
13
18
  print(f" - {match}")
14
19
 
15
20
 
16
- def suggest_close_name_matches(artefact_name: str, all_artefact_names: list[str]):
21
+ def suggest_close_name_matches(artefact_name: str, all_artefact_names: list[str], report_as_error: bool = False):
17
22
  message = f"No match found for artefact with name '{artefact_name}'"
18
23
 
19
24
  suggest_close_names(
20
25
  artefact_name=artefact_name,
21
26
  all_artefact_names=all_artefact_names,
22
- message=message
27
+ message=message,
28
+ report_as_error=report_as_error
23
29
  )
24
30
 
25
31
 
26
- def suggest_close_name_matches_for_parent(artefact_name: str, all_artefact_names: list[str], parent_name: str):
32
+ def suggest_close_name_matches_for_parent(artefact_name: str, all_artefact_names: list[str], parent_name: str, report_as_error: bool = False):
27
33
  message = f"No match found for parent of '{artefact_name}' with name '{parent_name}'"
28
34
 
29
35
  suggest_close_names(
30
36
  artefact_name=parent_name,
31
37
  all_artefact_names=all_artefact_names,
32
- message=message
38
+ message=message,
39
+ report_as_error=report_as_error
33
40
  )
34
41
 
35
42
 
36
- def find_closest_name_match(artefact_name: str, all_artefact_names: list[str]) -> Optional[str]:
37
- closest_matches = difflib.get_close_matches(artefact_name, all_artefact_names, cutoff=0.5, n=1)
43
+ def find_closest_name_matches(artefact_name: str, all_artefact_names: list[str]) -> Optional[str]:
44
+ closest_matches = difflib.get_close_matches(artefact_name, all_artefact_names, cutoff=0.5)
38
45
  if not closest_matches:
39
46
  return None
40
- closest_match = closest_matches[0]
41
- return closest_match
47
+ return closest_matches
48
+
49
+
50
+ def extract_artefact_names_of_classifier(classified_files: dict[str, list[dict]], classifier: str):
51
+ artefact_info_of_classifier = classified_files.get(classifier, [])
52
+ titles = list(map(lambda artefact: artefact['title'], artefact_info_of_classifier))
53
+ return titles
42
54
 
43
55
 
44
56
  def find_closest_rule(parent_artefact: 'Artefact', rule: str):
@@ -34,7 +34,7 @@ class ArtefactLinkUpdater:
34
34
  # Check if it's a file and not a directory
35
35
  elif self.file_system.path.isfile(item_path) and Classifier.is_valid_classifier(extension):
36
36
  # Read the content of the file
37
- with open(item_path, 'r') as file:
37
+ with open(item_path, 'r', encoding='utf-8') as file:
38
38
  content = file.read()
39
39
 
40
40
  # Replace all occurrences of the old name with the new name using regular expressions
@@ -42,7 +42,7 @@ class ArtefactLinkUpdater:
42
42
  content = pattern.sub(replacement, content)
43
43
 
44
44
  # Write the updated content back to the file
45
- with open(item_path, 'w') as file:
45
+ with open(item_path, 'w', encoding='utf-8') as file:
46
46
  file.write(content)
47
47
 
48
48
  def remove_links_in_related_artefacts(self, artefact_name, dir_path="."):
@@ -65,12 +65,12 @@ class ArtefactLinkUpdater:
65
65
 
66
66
  # Check if it's a file and not a directory, and if extension is a valid artefact classifier
67
67
  elif self.file_system.path.isfile(item_path) and Classifier.is_valid_classifier(extension):
68
- with open(item_path, 'r') as file:
68
+ with open(item_path, 'r', encoding='utf-8') as file:
69
69
  content = file.read()
70
70
 
71
71
  # Remove the artefact name from 'Contributes to' and 'Illustrates' lines
72
72
  content = contribute_pattern.sub("Contributes to", content)
73
73
  content = illustrates_pattern.sub("Illustrates", content)
74
74
 
75
- with open(item_path, 'w') as file:
75
+ with open(item_path, 'w', encoding='utf-8') as file:
76
76
  file.write(content)
@@ -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=ArtefactLister.artefact_content_retrieval,
41
- file_path_retrieval=ArtefactLister.artefact_path_retrieval,
42
- tag_retrieval=ArtefactLister.artefact_tags_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 = [p for p in artefact_info if p["title"] == artefact_name]
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(artefacts_by_classifier, list_filter)
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 = [p for p in artefact_info if p["title"] == artefact_name]
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 = [info for info in artefact_info_dict if info["title"] == artefact_name]
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] + '.data'
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
@@ -2,9 +2,17 @@ from ara_cli.artefact_models.artefact_mapping import title_prefix_to_artefact_cl
2
2
 
3
3
 
4
4
  def artefact_from_content(content):
5
- relevant_lines = content.splitlines()[:2]
6
- for line in relevant_lines:
5
+ lines = content.splitlines()
6
+
7
+ # Look through more lines to find the title, skipping empty lines
8
+ for line in lines:
9
+ line = line.strip()
10
+ if not line: # Skip empty lines
11
+ continue
12
+ if line.startswith('@'): # Skip tag lines
13
+ continue
14
+
7
15
  for prefix, artefact_class in title_prefix_to_artefact_class.items():
8
- if line.strip().startswith(prefix):
16
+ if line.startswith(prefix):
9
17
  return artefact_class.deserialize(content)
10
18
  return None