metripy 0.2.7__py3-none-any.whl → 0.2.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 metripy might be problematic. Click here for more details.

@@ -9,8 +9,8 @@ class Parser:
9
9
  def parse(self, argv: list[str]) -> Config:
10
10
  config = Config()
11
11
 
12
- if argv[0] == "codemetrics.py" or argv[0] == "codemetrics":
13
- # TODO, fix when path ends with codemetrics.py
12
+ if argv[0] == "metripy.py" or argv[0] == "metripy":
13
+ # TODO, fix when path ends with metripy.py
14
14
  pass
15
15
  argv.pop(0)
16
16
 
@@ -1,5 +1,7 @@
1
+ from typing import Self
2
+
1
3
  class Dependency:
2
- def __init__(self, name: str, version: str):
4
+ def __init__(self, name: str, version: str|None):
3
5
  self.name = name
4
6
  self.version = version
5
7
  self.latest: str = ""
@@ -28,3 +30,16 @@ class Dependency:
28
30
  "downloads_monthly": self.downloads_monthly,
29
31
  "licenses": ",".join(self.license),
30
32
  }
33
+
34
+ @staticmethod
35
+ def get_lisence_distribution(dependencies: list[Self]) -> dict[str, int]:
36
+ license_by_type = {}
37
+
38
+ dependency: Dependency
39
+ for dependency in dependencies:
40
+ for license_name in dependency.license:
41
+ if license_name not in license_by_type.keys():
42
+ license_by_type[license_name] = 0
43
+ license_by_type[license_name] += 1
44
+
45
+ return license_by_type
@@ -23,47 +23,38 @@ class Pip:
23
23
  return [item for item in packages if item is not None]
24
24
 
25
25
  def get_from_requirements_txt(self, path: str) -> list[Dependency]:
26
- requirements = []
27
-
28
- pattern = re.compile(r"([a-zA-Z0-9_\-]+)([<>=!~]+[^\s]+)?")
29
26
  with open(os.path.join(path, "requirements.txt"), "r") as file:
30
27
  lines = file.readlines()
31
- for line in lines:
28
+ return self._parse_dependencies(lines)
32
29
 
33
- line = line.strip()
34
- if line and not line.startswith("#"):
35
- match = pattern.match(line)
36
- if match:
37
- name = match.group(1)
38
- version = match.group(2) if match.group(2) else None
39
- requirements.append(Dependency(name, version))
40
- return requirements
30
+ return []
41
31
 
42
32
  def get_from_pyproject_toml(self, path: str) -> list[Dependency]:
43
- dependencies = []
44
-
45
33
  with open(os.path.join(path, "pyproject.toml"), "r") as f:
46
34
  data = toml.load(f)
47
35
 
48
36
  # For PEP 621 / setuptools projects
49
37
  if "project" in data:
50
38
  deps = data["project"].get("dependencies", [])
51
- for dep in deps:
52
- # dep is a string like "requests>=2.32.5"
53
- # You can split it if needed
54
- if "==" in dep:
55
- name, version = dep.split("==")
56
- elif ">=" in dep:
57
- name, version = dep.split(">=")
58
- else:
59
- name, version = dep, None
60
- dependencies.append(
61
- Dependency(name.strip(), version.strip() if version else None)
62
- )
63
-
64
- return dependencies
39
+ return self._parse_dependencies(deps)
65
40
 
41
+ return []
42
+
43
+ def _parse_dependencies(self, lines: list[str]) -> list[Dependency]:
44
+ dependencies = []
45
+ for dep in lines:
46
+ dep = dep.strip()
47
+ if not dep or dep.startswith("#"):
48
+ continue
49
+ # dep is a string like "requests>=2.32.5"
50
+ if "==" in dep:
51
+ name, version = dep.split("==")
52
+ elif ">=" in dep:
53
+ name, version = dep.split(">=")
54
+ else:
55
+ name, version = dep, None
56
+ dependencies.append(
57
+ Dependency(name.strip(), version.strip() if version else None)
58
+ )
66
59
 
67
- if __name__ == "__main__":
68
- pip = Pip()
69
- pip.get_dependencies("./")
60
+ return dependencies
@@ -3,6 +3,7 @@ from metripy.Metric.Code.AggregatedMetrics import AggregatedMetrics
3
3
  from metripy.Metric.Code.FileMetrics import FileMetrics
4
4
  from metripy.Metric.Code.SegmentedMetrics import SegmentedMetrics
5
5
  from metripy.Metric.Git.GitMetrics import GitMetrics
6
+ from metripy.Dependency.Dependency import Dependency
6
7
 
7
8
 
8
9
  class ProjectMetrics:
@@ -53,3 +54,16 @@ class ProjectMetrics:
53
54
 
54
55
  def _avg(self, items: list[float | int]) -> float:
55
56
  return sum(items) / len(items)
57
+
58
+ def to_dict(self) -> dict:
59
+ data = {
60
+ "file_metrics": [m.to_dict() for m in self.file_metrics],
61
+ "aggregated": self.total_code_metrics.to_dict(),
62
+ "aggregated_segmented": self.total_code_metrics.to_dict_segmentation(),
63
+ }
64
+ if self.git_metrics:
65
+ data["git_metrics"] = self.git_metrics.to_dict()
66
+ if self.dependencies:
67
+ data["dependencies"] = [d.to_dict() for d in self.dependencies]
68
+ data["license_distribution"] = Dependency.get_lisence_distribution(self.dependencies)
69
+ return data
@@ -10,6 +10,7 @@ from metripy.Component.Output.CliOutput import CliOutput
10
10
  from metripy.Metric.FileTree.FileTreeParser import FileTreeParser
11
11
  from metripy.Metric.ProjectMetrics import ProjectMetrics
12
12
  from metripy.Report.ReporterInterface import ReporterInterface
13
+ from metripy.Dependency.Dependency import Dependency
13
14
 
14
15
 
15
16
  class Reporter(ReporterInterface):
@@ -71,10 +72,10 @@ class Reporter(ReporterInterface):
71
72
  "segmentation_data": json.dumps(
72
73
  metrics.total_code_metrics.to_dict_segmentation(), indent=4
73
74
  ),
74
- "project_name": "CodeMetrics",
75
+ "project_name": "Metripy",
75
76
  "last_updated": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
76
77
  "date": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
77
- "author": "CodeMetrics",
78
+ "author": "Metripy",
78
79
  "version": "1.0.0",
79
80
  },
80
81
  )
@@ -107,14 +108,8 @@ class Reporter(ReporterInterface):
107
108
 
108
109
  dependencies = metrics.dependencies if metrics.dependencies is not None else []
109
110
 
110
- license_by_type = {}
111
-
112
111
  # TODO render a pie chart
113
- for dependency in dependencies:
114
- for license_name in dependency.license:
115
- if license_name not in license_by_type.keys():
116
- license_by_type[license_name] = 0
117
- license_by_type[license_name] += 1
112
+ license_by_type = Dependency.get_lisence_distribution(dependencies)
118
113
 
119
114
  print(json.dumps(license_by_type, indent=2))
120
115
 
@@ -122,7 +117,7 @@ class Reporter(ReporterInterface):
122
117
  "dependencies.html",
123
118
  {
124
119
  "dependencies": [d.to_dict() for d in dependencies],
125
- "project_name": "CodeMetrics",
120
+ "project_name": "Metripy",
126
121
  "last_updated": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
127
122
  },
128
123
  )
@@ -148,7 +143,7 @@ class Reporter(ReporterInterface):
148
143
  {
149
144
  "filetree": json.dumps(filetree.to_dict()),
150
145
  "file_details": json.dumps(file_details),
151
- "project_name": "CodeMetrics",
146
+ "project_name": "Metripy",
152
147
  "last_updated": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
153
148
  },
154
149
  )
@@ -194,7 +189,7 @@ class Reporter(ReporterInterface):
194
189
  "git_hotspots_data": metrics.git_metrics.get_hotspots_list()[
195
190
  :10
196
191
  ], # hotspots list
197
- "project_name": "CodeMetrics",
192
+ "project_name": "Metripy",
198
193
  "last_updated": metrics.git_metrics.get_analysis_start_date(),
199
194
  }
200
195
  ),
@@ -19,3 +19,4 @@ class GitJsonReporter(AbstractJsonReporter):
19
19
  }
20
20
 
21
21
  self.put_data(data)
22
+ self.output.writeln(f"<success>Create git json report in {self.config.path}</success>")
@@ -1,12 +1,13 @@
1
1
  from metripy.Application.Config.Config import Config
2
2
  from metripy.Component.Output.CliOutput import CliOutput
3
3
  from metripy.Metric.ProjectMetrics import ProjectMetrics
4
+ from metripy.Report.Json.AbstractJsonReporter import AbstractJsonReporter
4
5
 
5
-
6
- class JsonReporter:
6
+ class JsonReporter(AbstractJsonReporter):
7
7
  def __init__(self, config: Config, output: CliOutput):
8
8
  self.config = config
9
9
  self.output = output
10
10
 
11
11
  def generate(self, metrics: ProjectMetrics):
12
- raise NotImplementedError
12
+ self.put_data(metrics.to_dict())
13
+ self.output.writeln(f"<success>Create json report in {self.config.path}</success>")
@@ -3,6 +3,7 @@ from metripy.Component.Output.CliOutput import CliOutput
3
3
  from metripy.Report import ReporterInterface
4
4
  from metripy.Report.Html.Reporter import Reporter as HtmlReporter
5
5
  from metripy.Report.Json.GitJsonReporter import GitJsonReporter
6
+ from metripy.Report.Json.JsonReporter import JsonReporter
6
7
 
7
8
 
8
9
  class ReporterFactory:
@@ -11,7 +12,7 @@ class ReporterFactory:
11
12
  if config.type == "html":
12
13
  return HtmlReporter(config, output)
13
14
  elif config.type == "json":
14
- raise NotImplementedError
15
+ return JsonReporter(config, output)
15
16
  elif config.type == "csv":
16
17
  raise NotImplementedError
17
18
  elif config.type == "cli":
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metripy
3
- Version: 0.2.7
3
+ Version: 0.2.8
4
4
  Summary: A Python tool to generate multi project, multi language code metric reports
5
5
  Author-email: Yannick Zimmermann <yannick.zimmermann@proton.me>
6
6
  License: MIT
7
- Project-URL: Homepage, https://github.com/zimmer-yan/codemetrics
8
- Project-URL: Repository, https://github.com/zimmer-yan/codemetrics
9
- Project-URL: Documentation, https://github.com/zimmer-yan/codemetrics#readme
10
- Project-URL: Bug Tracker, https://github.com/zimmer-yan/codemetrics/issues
7
+ Project-URL: Homepage, https://github.com/zimmer-yan/metripy
8
+ Project-URL: Repository, https://github.com/zimmer-yan/metripy
9
+ Project-URL: Documentation, https://github.com/zimmer-yan/metripy#readme
10
+ Project-URL: Bug Tracker, https://github.com/zimmer-yan/metripy/issues
11
11
  Keywords: code metrics,multi-language,code analysis,git metrics,code visualization,software quality,static analysis,repository insights,developer productivity,codebase health,technical debt,language-agnostic
12
12
  Classifier: Development Status :: 3 - Alpha
13
13
  Classifier: Intended Audience :: Developers
@@ -37,7 +37,7 @@ Requires-Dist: poethepoet==0.37.0; extra == "dev"
37
37
  Requires-Dist: isort==7.0.0; extra == "dev"
38
38
  Dynamic: license-file
39
39
 
40
- # Codemetrics
40
+ # Metripy
41
41
  A multilanguage, multi project code metrics analysis tool.
42
42
 
43
43
  # Languages
@@ -102,8 +102,8 @@ Sample configuraiton:
102
102
  "pip": true,
103
103
  // looks for base_path/requirements.txt or base_path/pyproject.toml and analyzes dependencies - for python projects
104
104
  "reports": {
105
- "html": "./build/report/codemetrics", // report should be put into this directory
106
- "json-git": "./build/json-report/codemetrics-git.json" // file where to put git json report
105
+ "html": "./build/report/metripy", // report should be put into this directory
106
+ "json-git": "./build/json-report/metripy-git.json" // file where to put git json report
107
107
  // more types of reports TBA
108
108
  }
109
109
  },
@@ -111,3 +111,20 @@ Sample configuraiton:
111
111
  }
112
112
  }
113
113
  ```
114
+
115
+ ## Configuration for only git stats
116
+ ```json
117
+ {
118
+ "configs": {
119
+ "metripy-git": {
120
+ "base_path": "./",
121
+ "git": {
122
+ "branch": "main"
123
+ },
124
+ "reports": {
125
+ "json-git": "./build/json-report/metripy-git.json"
126
+ }
127
+ }
128
+ }
129
+ }
130
+ ```
@@ -5,7 +5,7 @@ metripy/Application/Application.py,sha256=mmvb2Af3AsfcDVwhf5LB5xVWxE5XmKSSaW_IY7
5
5
  metripy/Application/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  metripy/Application/Config/Config.py,sha256=VyBBYtbVNkrdevxkIGlASSCgK7pmq2WLW6DVKUMb6B4,353
7
7
  metripy/Application/Config/GitConfig.py,sha256=4y676GYv-FH6QyLxh6IQn64gUG9xOQciMgkXH9pJtb4,220
8
- metripy/Application/Config/Parser.py,sha256=T5o17gYpIE1Njiik1vaITCcDgq9szTU6GcQcPl_ufUg,904
8
+ metripy/Application/Config/Parser.py,sha256=ej3wT8AYtAVg-3q59FtkFb_-pxfy7Hvn4YswAVL8M4A,892
9
9
  metripy/Application/Config/ProjectConfig.py,sha256=N2xPkc10NF3mHywR36vpxsrcdJyw-VTFzbwQpLq5uHw,932
10
10
  metripy/Application/Config/ReportConfig.py,sha256=Vh3S1n2nyH5YNmt8JrfGRTcmYZuqLMxyFnFF5mmxu_4,259
11
11
  metripy/Application/Config/File/ConfigFileReaderFactory.py,sha256=K6p5x5TgF6I0acfq3dnU_wKWRWMD-e1EEa0_nrf7t8g,925
@@ -15,12 +15,12 @@ metripy/Component/Debug/Debugger.py,sha256=LhkHzUGNSEPvIvcjZJJob5Fjg5NQhk7Rs43y1
15
15
  metripy/Component/File/Finder.py,sha256=1vP3KD98zxBuIShNlfCOVVLbjOQPLJnrIsUvLzxnVnM,1399
16
16
  metripy/Component/Output/CliOutput.py,sha256=XJ5vJa7jxoukk4fRuj1UVV7GNkkZx-4Jb_Pl7ZYOSFk,1197
17
17
  metripy/Component/Output/ProgressBar.py,sha256=PmYQYwINXn9sYO0FKqT8tF-FaFLrPko-lJfi6jxbNsA,725
18
- metripy/Dependency/Dependency.py,sha256=6YSuNPEAbJY5MZ_8ZwMyppnWA_j84dwKx_hzm0eYmYc,1002
18
+ metripy/Dependency/Dependency.py,sha256=Y2j3xIMvPStzaW_TmsNx122gUxTYTnOGuMIgoUgVLVs,1482
19
19
  metripy/Dependency/Composer/Composer.py,sha256=tOVo8-NJfn0bRK-K4-hhq394tfigOtE6-5ZXOPTb_jw,1033
20
20
  metripy/Dependency/Composer/Packegist.py,sha256=ioeIwNg6Yhz0bk13UpB7saq4eqB0-3Zy9PdfcE3CIbA,1980
21
21
  metripy/Dependency/Npm/Npm.py,sha256=OB05MZJ312dRw909Pj4Np4bqHQ5oVOylqnzdfXdRvhM,975
22
22
  metripy/Dependency/Npm/NpmOrg.py,sha256=9igY0dZRP2L36jcCsn8I8WgfxjWhJ2FShcIV9ph-Zfs,1551
23
- metripy/Dependency/Pip/Pip.py,sha256=4OydPjP-EK5PRWJfjL9vjFacyTRML1fYs_J9MuC_hrI,2318
23
+ metripy/Dependency/Pip/Pip.py,sha256=b-XkyDGnLISfAchsD9Lo-M03rUZogGlvkhntC2h7WoI,1911
24
24
  metripy/Dependency/Pip/PyPi.py,sha256=Hqpk5rUw-sN23tgWVUaYMuLN43BR8LdbmNJzkKq9gEo,1612
25
25
  metripy/Git/GitAnalyzer.py,sha256=k1396AKkZHlCHZZTtlBHMNO73Cnhcte2ageXJo4ObVY,3071
26
26
  metripy/LangAnalyzer/AbstractLangAnalyzer.py,sha256=Wa7ucL7Wy6J8f13GyCOjRKYFgPuJPuZjE8t24fDUf2U,1896
@@ -37,7 +37,7 @@ metripy/LangAnalyzer/Typescript/TypescriptAstParser.py,sha256=6kEw3tm9_eIOXkBY_V
37
37
  metripy/LangAnalyzer/Typescript/TypescriptBasicComplexityAnalyzer.py,sha256=abQXNPywSoplozwwV1qm8tRKyPkCAhxBF8gHigECeZ0,3797
38
38
  metripy/LangAnalyzer/Typescript/TypescriptBasicLocAnalyzer.py,sha256=hxNqVGDUBb0Dy4cvQFTqfz5cCJTQ8B4uWu9hBnzSO2Y,2336
39
39
  metripy/LangAnalyzer/Typescript/TypescriptHalSteadAnalyzer.py,sha256=yOW_55R4PcTNA2BffCiugqkBH1ONuYkZCFo2No4hz0w,1278
40
- metripy/Metric/ProjectMetrics.py,sha256=dYAlObYrdIGV6qvcP0_amdRIL66vvVipDeuq2gMax0Y,2094
40
+ metripy/Metric/ProjectMetrics.py,sha256=YE6-C4kdVyMBqrzTXmPl9HSDk0wqEeOKYGziIYI5Lw0,2735
41
41
  metripy/Metric/Code/AggregatedMetrics.py,sha256=fLAuvM6f_ToFICQMsxZ8azNv2OTBQvbzETCJ8vA9SQY,1559
42
42
  metripy/Metric/Code/FileMetrics.py,sha256=BnAhjHeJawBV8X4EOLtJ4-aL-VmfKj4AGXmEoRV-gQE,1150
43
43
  metripy/Metric/Code/ModuleMetrics.py,sha256=J0eKYFm_m3lIJUjU0YkoADPs6HvNxHkJXHr69QTKXl8,1185
@@ -48,19 +48,19 @@ metripy/Metric/Git/GitCodeHotspot.py,sha256=zdqmXZu9cELpJ7-KGTW3tbmD2so2R6c0w1gY
48
48
  metripy/Metric/Git/GitContributor.py,sha256=Sn3Rmds7tr1H6CsR8bJ2cfuwG7tRj0vVadD28dKa6OE,1172
49
49
  metripy/Metric/Git/GitKnowledgeSilo.py,sha256=arla_KR2zyfw9O5QPDhxBrkc-bfQ-pvQuA6GUgv2c44,946
50
50
  metripy/Metric/Git/GitMetrics.py,sha256=k-MOdHaT6nOgHjQlRjjhrjIk9UjKiPMNKfjNP2WcWjM,5769
51
- metripy/Report/ReporterFactory.py,sha256=JKjQVGShC0PPUT5HiIuJ2lgzloQ5lHNeA5SSK8AciWU,897
51
+ metripy/Report/ReporterFactory.py,sha256=LzB2rMGaTUyEHQ0R3wy4MC8C3yVds16rpDe2TGExFoE,965
52
52
  metripy/Report/ReporterInterface.py,sha256=OZEE3SXpTKNOKQBzPytqxqViUFzPhlBUjkBTMlib0qE,543
53
53
  metripy/Report/Csv/Reporter.py,sha256=rC52vfJYavB_9yZ3-QA7aRF0Ez34lkiBOpw2mWll2m8,431
54
- metripy/Report/Html/Reporter.py,sha256=rHl8IYVJqy_GItGBPAdkEoLntIGB-pieIXMMdNnMv50,8638
54
+ metripy/Report/Html/Reporter.py,sha256=ePKXp1ZEwRSb5s2a0kjSobtiYDkr0YZ2SYcDeF2lLL4,8457
55
55
  metripy/Report/Json/AbstractJsonReporter.py,sha256=yqpBOO6MAN2HdhwoWOZ7Ler38WbV8DcG5g2oASXe-i8,343
56
- metripy/Report/Json/GitJsonReporter.py,sha256=4mOmoBSuCDzMSnQRAoWRckI6MPGig_25IDVwklBfuvk,850
57
- metripy/Report/Json/JsonReporter.py,sha256=6r1dIoVyGVr-Jds34SGmdGa8SJihy9_qYpkxZZ4ECQ0,390
56
+ metripy/Report/Json/GitJsonReporter.py,sha256=-kirTcruclxGnbEAMdE3waPO8jLoIaFCphJiKkFkQ9M,946
57
+ metripy/Report/Json/JsonReporter.py,sha256=To9sr2OJ39OqaAO1ynhy1fm4SK8Pa69Ubaf-YV-uRns,584
58
58
  metripy/Tree/ClassNode.py,sha256=uh2JJ3s9H6sCcj_ppElODUvvA525oHVnuhrW-ktzMj8,916
59
59
  metripy/Tree/FunctionNode.py,sha256=c2T78uGVkNRF_c2jCVmtfAwNFeY3MgASbUApROAsl3c,1520
60
60
  metripy/Tree/ModuleNode.py,sha256=YHlkAJKWWjy1oAhg7IdrvYnTOxpBYnq_VJS_ykey5_Y,1238
61
- metripy-0.2.7.dist-info/licenses/LICENSE,sha256=RQUMdlYUkqBhJgf7iIlzqrlaYz8VGr6KAn60wkv3FzE,1067
62
- metripy-0.2.7.dist-info/METADATA,sha256=dzY1Cec6ZAMyfLNZRcY2yKkACKkQwekQU9A7u7zNT38,3879
63
- metripy-0.2.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
64
- metripy-0.2.7.dist-info/entry_points.txt,sha256=vZI1vreNyXX9XGDUQlOnE2cSBRWNyXOlXXFnEBsVNIA,49
65
- metripy-0.2.7.dist-info/top_level.txt,sha256=Z-tn-27QGcxzNrsRq7BNPQv2BlXJnMCp8bp2sPdde1Y,8
66
- metripy-0.2.7.dist-info/RECORD,,
61
+ metripy-0.2.8.dist-info/licenses/LICENSE,sha256=7I-LBXpo2Lveofzf06uDAmq0wPN7zbMwInrQZiQCiwc,1063
62
+ metripy-0.2.8.dist-info/METADATA,sha256=XBX7suXhXc9RC_UeYDDx8LDaHdOAn_T5tTr0t9gcjiA,4168
63
+ metripy-0.2.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
64
+ metripy-0.2.8.dist-info/entry_points.txt,sha256=vZI1vreNyXX9XGDUQlOnE2cSBRWNyXOlXXFnEBsVNIA,49
65
+ metripy-0.2.8.dist-info/top_level.txt,sha256=Z-tn-27QGcxzNrsRq7BNPQv2BlXJnMCp8bp2sPdde1Y,8
66
+ metripy-0.2.8.dist-info/RECORD,,
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 CodeMetrics
3
+ Copyright (c) 2024 Metripy
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal