msgram 3.2.2__tar.gz → 3.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. {msgram-3.2.2 → msgram-3.3.0}/PKG-INFO +2 -2
  2. {msgram-3.2.2 → msgram-3.3.0}/msgram.egg-info/PKG-INFO +2 -2
  3. {msgram-3.2.2 → msgram-3.3.0}/msgram.egg-info/SOURCES.txt +2 -0
  4. {msgram-3.2.2 → msgram-3.3.0}/msgram.egg-info/requires.txt +1 -1
  5. {msgram-3.2.2 → msgram-3.3.0}/pyproject.toml +2 -2
  6. {msgram-3.2.2 → msgram-3.3.0}/src/cli/commands/cmd_calculate.py +35 -23
  7. {msgram-3.2.2 → msgram-3.3.0}/src/cli/commands/cmd_diff.py +13 -6
  8. msgram-3.3.0/src/cli/commands/cmd_extract.py +237 -0
  9. {msgram-3.2.2 → msgram-3.3.0}/src/cli/commands/cmd_list.py +1 -0
  10. {msgram-3.2.2 → msgram-3.3.0}/src/cli/commands/cmd_norm_diff.py +9 -16
  11. {msgram-3.2.2 → msgram-3.3.0}/src/cli/jsonReader/jsonReader.py +8 -7
  12. {msgram-3.2.2 → msgram-3.3.0}/src/cli/parsers.py +55 -60
  13. msgram-3.3.0/src/cli/resources/perf_eff_measure.py +165 -0
  14. msgram-3.3.0/src/cli/resources/perf_eff_parser.py +76 -0
  15. {msgram-3.2.2 → msgram-3.3.0}/src/cli/utils.py +22 -0
  16. {msgram-3.2.2 → msgram-3.3.0}/tests/system/test_extract.py +2 -6
  17. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_calculate.py +71 -17
  18. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_diff.py +33 -0
  19. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_extract.py +33 -75
  20. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_jsonReader.py +1 -3
  21. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_parser.py +5 -16
  22. msgram-3.2.2/src/cli/commands/cmd_extract.py +0 -176
  23. {msgram-3.2.2 → msgram-3.3.0}/LICENSE +0 -0
  24. {msgram-3.2.2 → msgram-3.3.0}/README.md +0 -0
  25. {msgram-3.2.2 → msgram-3.3.0}/msgram.egg-info/dependency_links.txt +0 -0
  26. {msgram-3.2.2 → msgram-3.3.0}/msgram.egg-info/entry_points.txt +0 -0
  27. {msgram-3.2.2 → msgram-3.3.0}/msgram.egg-info/top_level.txt +0 -0
  28. {msgram-3.2.2 → msgram-3.3.0}/setup.cfg +0 -0
  29. {msgram-3.2.2 → msgram-3.3.0}/src/__init__.py +0 -0
  30. {msgram-3.2.2 → msgram-3.3.0}/src/cli/__init__.py +0 -0
  31. {msgram-3.2.2 → msgram-3.3.0}/src/cli/aggregate_metrics.py +0 -0
  32. {msgram-3.2.2 → msgram-3.3.0}/src/cli/cli.py +0 -0
  33. {msgram-3.2.2 → msgram-3.3.0}/src/cli/commands/__init__.py +0 -0
  34. {msgram-3.2.2 → msgram-3.3.0}/src/cli/commands/cmd_init.py +0 -0
  35. {msgram-3.2.2 → msgram-3.3.0}/src/cli/exceptions/__init__.py +0 -0
  36. {msgram-3.2.2 → msgram-3.3.0}/src/cli/exceptions/exceptions.py +0 -0
  37. {msgram-3.2.2 → msgram-3.3.0}/src/cli/jsonReader/__init__.py +0 -0
  38. {msgram-3.2.2 → msgram-3.3.0}/src/cli/resources/__init__.py +0 -0
  39. {msgram-3.2.2 → msgram-3.3.0}/src/cli/resources/characteristic.py +0 -0
  40. {msgram-3.2.2 → msgram-3.3.0}/src/cli/resources/measure.py +0 -0
  41. {msgram-3.2.2 → msgram-3.3.0}/src/cli/resources/metrics.py +0 -0
  42. {msgram-3.2.2 → msgram-3.3.0}/src/cli/resources/subcharacteristic.py +0 -0
  43. {msgram-3.2.2 → msgram-3.3.0}/src/cli/resources/tsqmi.py +0 -0
  44. {msgram-3.2.2 → msgram-3.3.0}/src/config/__init__.py +0 -0
  45. {msgram-3.2.2 → msgram-3.3.0}/src/config/settings.py +0 -0
  46. {msgram-3.2.2 → msgram-3.3.0}/src/config/setup_log.py +0 -0
  47. {msgram-3.2.2 → msgram-3.3.0}/tests/__init__.py +0 -0
  48. {msgram-3.2.2 → msgram-3.3.0}/tests/system/__init__.py +0 -0
  49. {msgram-3.2.2 → msgram-3.3.0}/tests/system/test_help.py +0 -0
  50. {msgram-3.2.2 → msgram-3.3.0}/tests/system/test_init.py +0 -0
  51. {msgram-3.2.2 → msgram-3.3.0}/tests/system/test_list.py +0 -0
  52. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/__init__.py +0 -0
  53. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/data/file_reader_response.py +0 -0
  54. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_aggregate.py +0 -0
  55. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_characteristic.py +0 -0
  56. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_init.py +0 -0
  57. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_list.py +0 -0
  58. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_measures.py +0 -0
  59. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_norm_diff.py +0 -0
  60. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_setup_log.py +0 -0
  61. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_subcharacteristic.py +0 -0
  62. {msgram-3.2.2 → msgram-3.3.0}/tests/unit/test_tsqmi.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: msgram
3
- Version: 3.2.2
3
+ Version: 3.3.0
4
4
  Summary: The msgram CLI is a command-line interface to use MeasureSoftGram software
5
5
  Author-email: MeasureSoftGram <measuresoftgram@gmail.com>
6
6
  License: GNU AFFERO GENERAL PUBLIC LICENSE
@@ -684,7 +684,7 @@ Requires-Dist: setuptools~=72.1.0
684
684
  Requires-Dist: python-dotenv
685
685
  Requires-Dist: rich
686
686
  Requires-Dist: validators~=0.33.0
687
- Requires-Dist: msgram-core~=1.4.9
687
+ Requires-Dist: msgram-core~=1.5.3
688
688
  Requires-Dist: msgram-parser~=1.2.1
689
689
  Requires-Dist: anytree
690
690
  Provides-Extra: dev
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: msgram
3
- Version: 3.2.2
3
+ Version: 3.3.0
4
4
  Summary: The msgram CLI is a command-line interface to use MeasureSoftGram software
5
5
  Author-email: MeasureSoftGram <measuresoftgram@gmail.com>
6
6
  License: GNU AFFERO GENERAL PUBLIC LICENSE
@@ -684,7 +684,7 @@ Requires-Dist: setuptools~=72.1.0
684
684
  Requires-Dist: python-dotenv
685
685
  Requires-Dist: rich
686
686
  Requires-Dist: validators~=0.33.0
687
- Requires-Dist: msgram-core~=1.4.9
687
+ Requires-Dist: msgram-core~=1.5.3
688
688
  Requires-Dist: msgram-parser~=1.2.1
689
689
  Requires-Dist: anytree
690
690
  Provides-Extra: dev
@@ -28,6 +28,8 @@ src/cli/resources/__init__.py
28
28
  src/cli/resources/characteristic.py
29
29
  src/cli/resources/measure.py
30
30
  src/cli/resources/metrics.py
31
+ src/cli/resources/perf_eff_measure.py
32
+ src/cli/resources/perf_eff_parser.py
31
33
  src/cli/resources/subcharacteristic.py
32
34
  src/cli/resources/tsqmi.py
33
35
  src/config/__init__.py
@@ -8,7 +8,7 @@ setuptools~=72.1.0
8
8
  python-dotenv
9
9
  rich
10
10
  validators~=0.33.0
11
- msgram-core~=1.4.9
11
+ msgram-core~=1.5.3
12
12
  msgram-parser~=1.2.1
13
13
  anytree
14
14
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "msgram"
7
- version = "3.2.2"
7
+ version = "3.3.0"
8
8
  description = "The msgram CLI is a command-line interface to use MeasureSoftGram software"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -32,7 +32,7 @@ dependencies = [
32
32
  "python-dotenv",
33
33
  "rich",
34
34
  "validators~=0.33.0",
35
- "msgram-core~=1.4.9",
35
+ "msgram-core~=1.5.3",
36
36
  "msgram-parser~=1.2.1",
37
37
  "anytree"
38
38
  ]
@@ -16,9 +16,9 @@ from src.cli.resources.measure import calculate_measures
16
16
  from src.cli.resources.tsqmi import calculate_tsqmi
17
17
  from src.cli.resources.subcharacteristic import calculate_subcharacteristics
18
18
  from src.cli.utils import print_error, print_info, print_panel, print_rule, print_table
19
- from src.cli.aggregate_metrics import aggregate_metrics
20
19
  from src.cli.exceptions import exceptions
21
20
  from src.config.settings import DEFAULT_CONFIG_PATH, FILE_CONFIG
21
+ from src.cli.resources.perf_eff_measure import calculate_perf_eff_measures
22
22
 
23
23
  logger = logging.getLogger("msgram")
24
24
 
@@ -34,23 +34,33 @@ def read_config_file(config_path):
34
34
  exit(1)
35
35
 
36
36
 
37
- def calculate_metrics(input_format, extracted_path, config):
37
+ # calculate_sonar
38
+ # calculate_github
39
+
40
+
41
+ def calculate_metrics(extracted_path, config):
38
42
  data_calculated = []
39
43
 
44
+ print(extracted_path)
40
45
  if not extracted_path.is_file():
41
- if not aggregate_metrics(input_format, extracted_path, config):
42
- print_error(
43
- "> [red] Failed to aggregate metrics, calculate was not performed. \n"
44
- )
45
- return data_calculated, False
46
-
47
- for file, file_name in read_multiple_files(
48
- extracted_path, input_format, "metrics"
49
- ):
50
- if file_name.startswith("github_"):
51
- file_name = file_name[len("github_") :]
52
- result = calculate_all(file, file_name, config)
53
- data_calculated.append(result)
46
+ # should not aggregate
47
+ # if not aggregate_metrics(input_format, extracted_path, config):
48
+ # print_error(
49
+ # "> [red] Failed to aggregate metrics, calculate was not performed. \n"
50
+ # )
51
+ # return data_calculated, False
52
+
53
+ for file, file_name in read_multiple_files(extracted_path, "metrics"):
54
+ print(file_name)
55
+ if file_name.startswith("perf-eff_"):
56
+ file_name = file_name[len("perf-eff_") :]
57
+ result = calculate_perf_eff_measures(file_name, file)
58
+ data_calculated.append(result)
59
+ else:
60
+ if file_name.startswith("github_"):
61
+ file_name = file_name[len("github_") :]
62
+ result = calculate_all(file, file_name, config)
63
+ data_calculated.append(result)
54
64
 
55
65
  return data_calculated, True
56
66
  else:
@@ -59,7 +69,8 @@ def calculate_metrics(input_format, extracted_path, config):
59
69
  if extracted_path.name.startswith("github_"):
60
70
  file_name = file_name[len("github_") :]
61
71
  result = calculate_all(open_json_file(extracted_path), file_name, config)
62
- return result, True
72
+ data_calculated.append(result)
73
+ return data_calculated, True
63
74
  except exceptions.MeasureSoftGramCLIException as e:
64
75
  print_error(f"[red]Error calculating {extracted_path}: {e}\n")
65
76
  return data_calculated, False
@@ -68,7 +79,7 @@ def calculate_metrics(input_format, extracted_path, config):
68
79
  def command_calculate(args):
69
80
  try:
70
81
  output_format: str = args["output_format"]
71
- input_format: str = args["input_format"]
82
+ # input_format: str = args["input_format"]
72
83
  config_path = args["config_path"]
73
84
  extracted_path = args["extracted_path"]
74
85
 
@@ -86,7 +97,7 @@ def command_calculate(args):
86
97
 
87
98
  print_info("\n> [blue] Reading extracted files:[/]")
88
99
 
89
- data_calculated, success = calculate_metrics(input_format, extracted_path, config)
100
+ data_calculated, success = calculate_metrics(extracted_path, config)
90
101
 
91
102
  if success:
92
103
  print_info("\n[#A9A9A9]All calculations performed[/] successfully!")
@@ -96,8 +107,9 @@ def command_calculate(args):
96
107
 
97
108
  print_panel(
98
109
  title="Done",
99
- menssage="> See our docs for more information: \n"
100
- " https://github.com/fga-eps-mds/2022-2-MeasureSoftGram-CLI",
110
+ menssage="> See the publications for more information: \n"
111
+ "https://dl.acm.org/doi/10.1145/3239235.3267438 \n"
112
+ "https://dl.acm.org/doi/10.1145/3422392.3422450 \n",
101
113
  )
102
114
 
103
115
 
@@ -139,13 +151,13 @@ def calculate_all(json_data, file_name, config):
139
151
  def show_results(output_format, data_calculated, config_path):
140
152
 
141
153
  if output_format == "tabular":
142
- show_tabulate(data_calculated)
154
+ show_tabulate(data_calculated[0])
143
155
 
144
156
  elif output_format == "raw":
145
- print(data_calculated)
157
+ print(data_calculated[0])
146
158
 
147
159
  elif output_format == "tree":
148
- show_tree(data_calculated, pre_config)
160
+ show_tree(data_calculated[0], pre_config)
149
161
 
150
162
  elif len(data_calculated) == 0:
151
163
  print_info(
@@ -15,6 +15,7 @@ from src.cli.utils import (
15
15
  print_info,
16
16
  print_panel,
17
17
  print_rule,
18
+ validate_json_values,
18
19
  )
19
20
  from src.cli.exceptions import exceptions
20
21
  from src.config.settings import DEFAULT_CONFIG_PATH
@@ -61,7 +62,7 @@ def read_calculated_file(extracted_calculation):
61
62
  exit(1)
62
63
 
63
64
 
64
- def calculate_diff(planned, calculated):
65
+ def calculate_diff(planned, calculated, rp_path, rd_path):
65
66
  formated_result = []
66
67
 
67
68
  try:
@@ -73,7 +74,7 @@ def calculate_diff(planned, calculated):
73
74
  )
74
75
 
75
76
  data_planned, data_calculated = extract_values(
76
- planned, calculated_item["characteristics"]
77
+ planned, calculated_item["characteristics"], rp_path, rd_path
77
78
  )
78
79
 
79
80
  diff_calculated = diff(data_planned, data_calculated)
@@ -124,7 +125,9 @@ def command_diff(args):
124
125
 
125
126
  calculated = read_calculated_file(extracted_calculation)
126
127
 
127
- diff_calculated, success = calculate_diff(planned, calculated)
128
+ diff_calculated, success = calculate_diff(
129
+ planned, calculated, config_path, extracted_calculation
130
+ )
128
131
 
129
132
  if success:
130
133
  print_info("\n[#A9A9A9]Diff calculation performed[/] successfully!")
@@ -136,8 +139,9 @@ def command_diff(args):
136
139
 
137
140
  print_panel(
138
141
  title="Done",
139
- menssage="> See our docs for more information: \n"
140
- " https://github.com/fga-eps-mds/2022-2-MeasureSoftGram-CLI",
142
+ menssage="> See the publications for more information: \n"
143
+ "https://dl.acm.org/doi/10.1145/3239235.3267438 \n"
144
+ "https://dl.acm.org/doi/10.1145/3422392.3422450 \n",
141
145
  )
142
146
 
143
147
 
@@ -208,7 +212,7 @@ def export_csv(data_calculated: list, file_path: Path = Path("DEFAULT_CONFIG_PAT
208
212
  print(f"Success: {file_path.name} exported as CSV")
209
213
 
210
214
 
211
- def extract_values(planned, calculated):
215
+ def extract_values(planned, calculated, rp_path, rd_path):
212
216
  vector_calculated = []
213
217
  vector_planned = []
214
218
 
@@ -221,4 +225,7 @@ def extract_values(planned, calculated):
221
225
  vector_calculated.append(calculated[x]["value"])
222
226
  vector_planned.append(planned[x]["value"])
223
227
 
228
+ validate_json_values(vector_planned, rp_path)
229
+ validate_json_values(vector_calculated, rd_path)
230
+
224
231
  return vector_planned, vector_calculated
@@ -0,0 +1,237 @@
1
+ from datetime import datetime
2
+ import json
3
+ import logging
4
+ import os
5
+ import re
6
+ import sys
7
+ from time import perf_counter
8
+ from pathlib import Path
9
+
10
+ from rich import print
11
+ from rich.console import Console
12
+ from genericparser import GenericParser
13
+
14
+ from src.cli.jsonReader import folder_reader
15
+ from src.cli.utils import (
16
+ make_progress_bar,
17
+ print_info,
18
+ print_panel,
19
+ print_rule,
20
+ print_warn,
21
+ is_valid_date_range,
22
+ )
23
+ from src.cli.resources.perf_eff_parser import parse_performance_efficiency_data
24
+
25
+ logger = logging.getLogger("msgram")
26
+
27
+
28
+ def get_infos_from_name(filename: str) -> str:
29
+ """
30
+ filename: str = fga-eps-mds-2022-1-MeasureSoftGram-Service-09-11-2022-16-11-42-develop.json
31
+ """
32
+ file_date = re.search(r"\d{1,2}-\d{1,2}-\d{4}-\d{1,2}-\d{1,2}", filename)
33
+
34
+ if not file_date:
35
+ message = (
36
+ "Could not extract creation date from file. Was the file name "
37
+ "to contain a date in the format dd-mm-yyyy-hh-mm"
38
+ )
39
+ print_warn(message)
40
+ print_warn(f"filename: {filename}")
41
+ sys.exit(1)
42
+
43
+ file_name = filename.split(".")[0]
44
+
45
+ return f"{file_name}-extracted.metrics"
46
+
47
+
48
+ def parse_input_quotes(user_input):
49
+ # Aspas para normalizar
50
+ quotes = "“‘«”’»"
51
+
52
+ if user_input:
53
+ # Remove aspas no início
54
+ user_input = user_input[1:] if user_input[0] in quotes else user_input
55
+
56
+ # Remove aspas no final
57
+ user_input = user_input[:-1] if user_input[-1] in quotes else user_input
58
+
59
+ return user_input
60
+
61
+
62
+ def extract_github(
63
+ extracted_path: Path,
64
+ gh_repository: str,
65
+ gh_date_range: str,
66
+ gh_label: str,
67
+ gh_workflows: str,
68
+ parser: GenericParser,
69
+ ):
70
+ input_origin = "github"
71
+ if gh_date_range is not None and not is_valid_date_range(gh_date_range):
72
+ logger.error(
73
+ "Error: Range of dates for filter must be in format 'dd/mm/yyyy-dd/mm/yyyy'"
74
+ )
75
+ print_warn(
76
+ "Error: Range of dates for filter must be in format 'dd/mm/yyyy-dd/mm/yyyy'"
77
+ )
78
+ sys.exit(1)
79
+ filters = {
80
+ "labels": gh_label if gh_label else "US,User Story,User Stories",
81
+ "workflows": gh_workflows.split(",") if gh_workflows else "build",
82
+ "dates": gh_date_range if gh_date_range else None,
83
+ }
84
+ print_info(f"\n> Extract and save metrics [[blue ]{input_origin}[/]]:")
85
+ result = parser.parse(
86
+ input_value=gh_repository, type_input=input_origin, filters=filters
87
+ )
88
+ repository_name = gh_repository.replace("/", "-")
89
+ save_file_with_results(
90
+ extracted_path,
91
+ gh_repository,
92
+ name=f"github_{repository_name}-{datetime.now().strftime('%d-%m-%Y-%H-%M-%S')}-extracted.metrics",
93
+ result=result,
94
+ )
95
+
96
+
97
+ def extract_sonar(extracted_path: Path, sonar_path: Path, parser: GenericParser):
98
+ time_init = perf_counter()
99
+ input_origin = "sonarqube"
100
+
101
+ logger.debug(f"input_origin: {input_origin}")
102
+ logger.debug(f"data_path: {sonar_path}")
103
+ logger.debug(f"extracted_path: {extracted_path}")
104
+
105
+ files = list(sonar_path.glob("*.json"))
106
+
107
+ if not files:
108
+ print_warn(f"No JSON files found in the specified data_path: {sonar_path}\n")
109
+ sys.exit(1)
110
+
111
+ valid_files = len(files)
112
+
113
+ print_info(f"\n> Extract and save metrics [[blue ]{input_origin}[/]]:")
114
+ with make_progress_bar() as progress_bar:
115
+ task_request = progress_bar.add_task(
116
+ "[#A9A9A9]Extracting files: ", total=len(files)
117
+ )
118
+ progress_bar.advance(task_request)
119
+
120
+ for component, filename, files_error in folder_reader(sonar_path, "json"):
121
+ if files_error:
122
+ progress_bar.update(task_request, advance=files_error)
123
+ valid_files = valid_files - files_error
124
+
125
+ name = get_infos_from_name(filename)
126
+ result = parser.parse(input_value=component, type_input=input_origin)
127
+
128
+ save_file_with_results(extracted_path, filename, name, result)
129
+
130
+ progress_bar.advance(task_request)
131
+
132
+ time_extract = perf_counter() - time_init
133
+ print_info(
134
+ f"\n\nMetrics successfully extracted [[blue bold]{valid_files}/{len(files)} "
135
+ f"files - {time_extract:0.2f} seconds[/]]!"
136
+ )
137
+
138
+
139
+ def extract_perf_eff():
140
+ pass
141
+
142
+
143
+ def command_extract(args):
144
+ try:
145
+ extracted_path = args["extracted_path"]
146
+ sonar_path = args.get("sonar_path", None)
147
+ gh_repository = args.get("gh_repository", None)
148
+ gh_label = args.get("gh_label", None)
149
+ gh_workflows = args.get("gh_workflows", None)
150
+ gh_date_range = args.get("gh_date_range", None)
151
+ pe_release1 = args.get("pe_release_1", None)
152
+ pe_release2 = args.get("pe_release_2", None)
153
+ pe_repository_name = args.get("pe_repository_name", None)
154
+
155
+ except Exception as e:
156
+ logger.error(f"KeyError: args[{e}] - non-existent parameters")
157
+ print_warn(f"KeyError: args[{e}] - non-existent parameters")
158
+ exit(1)
159
+
160
+ pe_params = (
161
+ (pe_release1 is not None)
162
+ + (pe_release2 is not None)
163
+ + (pe_repository_name is not None)
164
+ )
165
+ if pe_params > 0 and pe_params < 3:
166
+ print_warn(
167
+ "Error: Some pe_ parameters for extracting the performance efficiency data are missing"
168
+ )
169
+ exit()
170
+
171
+ # First check if sonar_path and gh_repository are none
172
+ if (sonar_path is None) and (gh_repository is None) and (pe_params == 0):
173
+ logger.error(
174
+ "It is necessary to pass sonar_path, github_repository or the pe_ parameters"
175
+ )
176
+ print_warn(
177
+ "It is necessary to pass sonar_path, github_repository or the pe_ parameters"
178
+ )
179
+ sys.exit(1)
180
+
181
+ console = Console()
182
+ console.clear()
183
+ print_rule("Extract metrics")
184
+ parser = GenericParser()
185
+
186
+ if not os.path.isdir(extracted_path):
187
+ logger.error(
188
+ f'FileNotFoundError: extract directory "{extracted_path}" does not exists'
189
+ )
190
+ print_warn(
191
+ f"FileNotFoundError: extract directory[blue]'{extracted_path}'[/]does not exists"
192
+ )
193
+ sys.exit(1)
194
+
195
+ # Github repository is defined so we should generate github metrics
196
+ if gh_repository:
197
+ extract_github(
198
+ extracted_path, gh_repository, gh_date_range, gh_label, gh_workflows, parser
199
+ )
200
+ elif gh_label or gh_workflows or gh_date_range:
201
+ logger.error(
202
+ "Error: gh_repository must be specified in order to use gh_ parameters"
203
+ )
204
+ print_warn(
205
+ "Error: gh_repository must be specified in order to use gh_ parameters"
206
+ )
207
+ sys.exit(1)
208
+
209
+ if pe_params == 3:
210
+ input_origin = "performance-efficiency"
211
+ print_info(f"\n> Extract and save metrics [[blue ]{input_origin}[/]]:")
212
+ # All pe_params are set, so we should extract the performance efficiency data
213
+ parsed_data = parse_performance_efficiency_data(
214
+ pe_release1, pe_release2, pe_repository_name
215
+ )
216
+ save_file_with_results(
217
+ extracted_path,
218
+ pe_repository_name,
219
+ name=f"perf-eff_{pe_repository_name}-{datetime.now().strftime('%d-%m-%Y-%H-%M-%S')}-extracted.metrics",
220
+ result=parsed_data,
221
+ )
222
+
223
+ # Sonargube path is defined so we should generate sonar metrics
224
+ if sonar_path:
225
+ extract_sonar(extracted_path, sonar_path, parser)
226
+
227
+ print_panel(
228
+ "> Run [#008080]msgram calculate all -ep 'extracted_path' -cp 'extracted_path' -o 'input_origin'"
229
+ )
230
+
231
+
232
+ def save_file_with_results(extracted_path, filename, name, result):
233
+ print(f"[dark_green]Reading:[/] [black]{filename}[/]")
234
+ print(f"[dark_green]Save :[/] [black]{name}[/]\n")
235
+
236
+ with open(f"{extracted_path}/{name}", "w") as f:
237
+ f.write(json.dumps(result, indent=2))
@@ -62,6 +62,7 @@ def print_json_tree(data):
62
62
  metrics = measure_to_metric.get(
63
63
  measure_key, []
64
64
  ) # Get associated metrics
65
+ min_max = ""
65
66
  for metric in metrics:
66
67
  result.append(
67
68
  f"[#FFFFFF]{indent}{indent}│ └─[#00FF00]{metric}"
@@ -1,7 +1,12 @@
1
1
  import logging
2
2
  from core.transformations import norm_diff
3
3
  from src.cli.jsonReader import open_json_file
4
- from src.cli.utils import print_error, print_info, print_rule
4
+ from src.cli.utils import (
5
+ print_error,
6
+ print_info,
7
+ print_rule,
8
+ validate_json_values,
9
+ )
5
10
  from src.cli.exceptions import exceptions
6
11
  import numpy as np
7
12
 
@@ -51,6 +56,7 @@ def command_norm_diff(args):
51
56
  exit(1)
52
57
 
53
58
  planned_data = read_planned_file(rp_path, sort_key="key")
59
+
54
60
  calculated_data = read_calculated_file(rd_path)
55
61
 
56
62
  planned_vector, calculated_vector = extract_values(
@@ -98,21 +104,8 @@ def extract_values(planned_data, calculated_data, rp_path, rd_path):
98
104
  planned_values = [planned_dict[key] for key in planned_keys]
99
105
  calculated_values = [calculated_dict[key] for key in planned_keys]
100
106
 
101
- for value in planned_values:
102
- if value > 1 or value < 0:
103
- print_error(
104
- f"[red]The values informed in the .json file {rp_path} must be between 0 and 1.\n"
105
- )
106
- print_rule()
107
- exit(1)
108
-
109
- for value in calculated_values:
110
- if value > 1 or value < 0:
111
- print_error(
112
- f"[red]The values informed in the .json file {rd_path} must be between 0 and 1.\n"
113
- )
114
- print_rule()
115
- exit(1)
107
+ validate_json_values(planned_values, rp_path)
108
+ validate_json_values(calculated_values, rd_path)
116
109
 
117
110
  return (np.array(planned_values), np.array(calculated_values))
118
111
  except exceptions.MeasureSoftGramCLIException as e:
@@ -29,13 +29,14 @@ def file_reader(path_file):
29
29
  return components
30
30
 
31
31
 
32
- def read_multiple_files(directory: Path, format: str, pattern: str):
33
- if format == "github":
34
- glob_pattern = f"github_*.{pattern}"
35
- elif format == "sonarqube":
36
- glob_pattern = f"[!github_]*.{pattern}"
37
- else:
38
- glob_pattern = f"*.{pattern}"
32
+ def read_multiple_files(directory: Path, pattern: str):
33
+ # if format == "github":
34
+ # glob_pattern = f"github_*.{pattern}"
35
+ # elif format == "sonarqube":
36
+ # glob_pattern = f"[!github_]*.{pattern}"
37
+ # else:
38
+ # glob_pattern = f"*.{pattern}"
39
+ glob_pattern = f"*.{pattern}"
39
40
 
40
41
  for path_file in directory.glob(glob_pattern):
41
42
  try: