metripy 0.2.5__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.

Files changed (71) hide show
  1. {src → metripy}/Application/Analyzer.py +17 -16
  2. {src → metripy}/Application/Application.py +7 -7
  3. {src → metripy}/Application/Config/Config.py +1 -1
  4. {src → metripy}/Application/Config/File/ConfigFileReaderFactory.py +4 -2
  5. {src → metripy}/Application/Config/File/ConfigFileReaderInterface.py +1 -1
  6. {src → metripy}/Application/Config/File/JsonConfigFileReader.py +6 -5
  7. {src → metripy}/Application/Config/Parser.py +5 -4
  8. {src → metripy}/Application/Config/ProjectConfig.py +2 -2
  9. {src → metripy}/Component/Debug/Debugger.py +1 -1
  10. {src → metripy}/Component/File/Finder.py +1 -1
  11. {src → metripy}/Component/Output/ProgressBar.py +1 -1
  12. {src → metripy}/Dependency/Composer/Composer.py +2 -2
  13. {src → metripy}/Dependency/Composer/Packegist.py +1 -1
  14. {src → metripy}/Dependency/Dependency.py +16 -1
  15. {src → metripy}/Dependency/Npm/Npm.py +2 -2
  16. {src → metripy}/Dependency/Npm/NpmOrg.py +1 -1
  17. metripy/Dependency/Pip/Pip.py +60 -0
  18. {src → metripy}/Dependency/Pip/PyPi.py +1 -1
  19. {src → metripy}/Git/GitAnalyzer.py +2 -2
  20. {src → metripy}/LangAnalyzer/AbstractLangAnalyzer.py +2 -2
  21. {src → metripy}/LangAnalyzer/Php/PhpAnalyzer.py +10 -10
  22. {src → metripy}/LangAnalyzer/Php/PhpHalSteadAnalyzer.py +1 -1
  23. {src → metripy}/LangAnalyzer/Python/PythonAnalyzer.py +6 -6
  24. {src → metripy}/LangAnalyzer/Typescript/TypescriptAnalyzer.py +14 -16
  25. {src → metripy}/LangAnalyzer/Typescript/TypescriptAstParser.py +1 -1
  26. {src → metripy}/LangAnalyzer/Typescript/TypescriptBasicComplexityAnalyzer.py +3 -3
  27. {src → metripy}/LangAnalyzer/Typescript/TypescriptHalSteadAnalyzer.py +1 -1
  28. {src → metripy}/Metric/Code/AggregatedMetrics.py +1 -1
  29. {src → metripy}/Metric/Code/FileMetrics.py +2 -2
  30. {src → metripy}/Metric/Code/ModuleMetrics.py +2 -2
  31. {src → metripy}/Metric/FileTree/FileTreeParser.py +1 -1
  32. {src → metripy}/Metric/Git/GitMetrics.py +3 -3
  33. {src → metripy}/Metric/ProjectMetrics.py +19 -5
  34. {src → metripy}/Report/Csv/Reporter.py +3 -3
  35. {src → metripy}/Report/Html/Reporter.py +12 -17
  36. {src → metripy}/Report/Json/AbstractJsonReporter.py +2 -1
  37. {src → metripy}/Report/Json/GitJsonReporter.py +3 -2
  38. metripy/Report/Json/JsonReporter.py +13 -0
  39. {src → metripy}/Report/ReporterFactory.py +7 -6
  40. {src → metripy}/Report/ReporterInterface.py +3 -3
  41. {src → metripy}/Tree/ClassNode.py +1 -1
  42. {src → metripy}/Tree/ModuleNode.py +2 -2
  43. src/codemetrics.py → metripy/metripy.py +1 -1
  44. {metripy-0.2.5.dist-info → metripy-0.2.8.dist-info}/METADATA +28 -10
  45. metripy-0.2.8.dist-info/RECORD +66 -0
  46. metripy-0.2.8.dist-info/entry_points.txt +2 -0
  47. {metripy-0.2.5.dist-info → metripy-0.2.8.dist-info}/licenses/LICENSE +1 -1
  48. metripy-0.2.8.dist-info/top_level.txt +1 -0
  49. metripy-0.2.5.dist-info/RECORD +0 -66
  50. metripy-0.2.5.dist-info/entry_points.txt +0 -2
  51. metripy-0.2.5.dist-info/top_level.txt +0 -1
  52. src/Dependency/Pip/Pip.py +0 -69
  53. src/Report/Json/JsonReporter.py +0 -12
  54. {src → metripy}/Application/Config/GitConfig.py +0 -0
  55. {src → metripy}/Application/Config/ReportConfig.py +0 -0
  56. {src → metripy}/Application/__init__.py +0 -0
  57. {src → metripy}/Component/Output/CliOutput.py +0 -0
  58. {src → metripy}/LangAnalyzer/Generic/HalSteadAnalyzer.py +0 -0
  59. {src → metripy}/LangAnalyzer/Generic/__init__.py +0 -0
  60. {src → metripy}/LangAnalyzer/Php/PhpBasicAstParser.py +0 -0
  61. {src → metripy}/LangAnalyzer/Php/PhpBasicLocAnalyzer.py +0 -0
  62. {src → metripy}/LangAnalyzer/Typescript/TypescriptBasicLocAnalyzer.py +0 -0
  63. {src → metripy}/LangAnalyzer/__init__.py +0 -0
  64. {src → metripy}/Metric/Code/SegmentedMetrics.py +0 -0
  65. {src → metripy}/Metric/FileTree/FileTree.py +0 -0
  66. {src → metripy}/Metric/Git/GitCodeHotspot.py +0 -0
  67. {src → metripy}/Metric/Git/GitContributor.py +0 -0
  68. {src → metripy}/Metric/Git/GitKnowledgeSilo.py +0 -0
  69. {src → metripy}/Tree/FunctionNode.py +0 -0
  70. {src → metripy}/__init__.py +0 -0
  71. {metripy-0.2.5.dist-info → metripy-0.2.8.dist-info}/WHEEL +0 -0
@@ -1,19 +1,20 @@
1
- from Application.Config.ProjectConfig import ProjectConfig
2
- from Component.Debug.Debugger import Debugger
3
- from Component.Output.CliOutput import CliOutput
4
- from Component.Output.ProgressBar import ProgressBar
5
- from Dependency.Composer.Composer import Composer
6
- from Dependency.Dependency import Dependency
7
- from Dependency.Npm.Npm import Npm
8
- from Dependency.Pip.Pip import Pip
9
- from Git.GitAnalyzer import GitAnalyzer
10
- from LangAnalyzer.AbstractLangAnalyzer import AbstractLangAnalyzer
11
- from LangAnalyzer.Php.PhpAnalyzer import PhpAnalyzer
12
- from LangAnalyzer.Python.PythonAnalyzer import PythonAnalyzer
13
- from LangAnalyzer.Typescript.TypescriptAnalyzer import TypescriptAnalyzer
14
- from Metric.Code.FileMetrics import FileMetrics
15
- from Metric.Git.GitMetrics import GitMetrics
16
- from Metric.ProjectMetrics import ProjectMetrics
1
+ from metripy.Application.Config.ProjectConfig import ProjectConfig
2
+ from metripy.Component.Debug.Debugger import Debugger
3
+ from metripy.Component.Output.CliOutput import CliOutput
4
+ from metripy.Component.Output.ProgressBar import ProgressBar
5
+ from metripy.Dependency.Composer.Composer import Composer
6
+ from metripy.Dependency.Dependency import Dependency
7
+ from metripy.Dependency.Npm.Npm import Npm
8
+ from metripy.Dependency.Pip.Pip import Pip
9
+ from metripy.Git.GitAnalyzer import GitAnalyzer
10
+ from metripy.LangAnalyzer.AbstractLangAnalyzer import AbstractLangAnalyzer
11
+ from metripy.LangAnalyzer.Php.PhpAnalyzer import PhpAnalyzer
12
+ from metripy.LangAnalyzer.Python.PythonAnalyzer import PythonAnalyzer
13
+ from metripy.LangAnalyzer.Typescript.TypescriptAnalyzer import \
14
+ TypescriptAnalyzer
15
+ from metripy.Metric.Code.FileMetrics import FileMetrics
16
+ from metripy.Metric.Git.GitMetrics import GitMetrics
17
+ from metripy.Metric.ProjectMetrics import ProjectMetrics
17
18
 
18
19
 
19
20
  class Analyzer:
@@ -1,12 +1,12 @@
1
1
  import json
2
2
 
3
- from Application.Analyzer import Analyzer
4
- from Application.Config.Parser import Parser
5
- from Component.Debug.Debugger import Debugger
6
- from Component.File.Finder import Finder
7
- from Component.Output.CliOutput import CliOutput
8
- from Report.ReporterFactory import ReporterFactory
9
- from Report.ReporterInterface import ReporterInterface
3
+ from metripy.Application.Analyzer import Analyzer
4
+ from metripy.Application.Config.Parser import Parser
5
+ from metripy.Component.Debug.Debugger import Debugger
6
+ from metripy.Component.File.Finder import Finder
7
+ from metripy.Component.Output.CliOutput import CliOutput
8
+ from metripy.Report.ReporterFactory import ReporterFactory
9
+ from metripy.Report.ReporterInterface import ReporterInterface
10
10
 
11
11
 
12
12
  class Application:
@@ -1,4 +1,4 @@
1
- from Application.Config.ProjectConfig import ProjectConfig
1
+ from metripy.Application.Config.ProjectConfig import ProjectConfig
2
2
 
3
3
 
4
4
  class Config:
@@ -1,8 +1,10 @@
1
1
  import os
2
2
  import pathlib
3
3
 
4
- from Application.Config.File.ConfigFileReaderInterface import ConfigFileReaderInterface
5
- from Application.Config.File.JsonConfigFileReader import JsonConfigFileReader
4
+ from metripy.Application.Config.File.ConfigFileReaderInterface import \
5
+ ConfigFileReaderInterface
6
+ from metripy.Application.Config.File.JsonConfigFileReader import \
7
+ JsonConfigFileReader
6
8
 
7
9
 
8
10
  class ConfigFileReaderFactory:
@@ -1,6 +1,6 @@
1
1
  from abc import ABC, abstractmethod
2
2
 
3
- from Application.Config.Config import Config
3
+ from metripy.Application.Config.Config import Config
4
4
 
5
5
 
6
6
  class ConfigFileReaderInterface(ABC):
@@ -1,11 +1,12 @@
1
1
  import json
2
2
  import os
3
3
 
4
- from Application.Config.Config import Config
5
- from Application.Config.File.ConfigFileReaderInterface import ConfigFileReaderInterface
6
- from Application.Config.GitConfig import GitConfig
7
- from Application.Config.ProjectConfig import ProjectConfig
8
- from Application.Config.ReportConfig import ReportConfig
4
+ from metripy.Application.Config.Config import Config
5
+ from metripy.Application.Config.File.ConfigFileReaderInterface import \
6
+ ConfigFileReaderInterface
7
+ from metripy.Application.Config.GitConfig import GitConfig
8
+ from metripy.Application.Config.ProjectConfig import ProjectConfig
9
+ from metripy.Application.Config.ReportConfig import ReportConfig
9
10
 
10
11
 
11
12
  class JsonConfigFileReader(ConfigFileReaderInterface):
@@ -1,15 +1,16 @@
1
1
  import re
2
2
 
3
- from Application.Config.Config import Config
4
- from Application.Config.File.ConfigFileReaderFactory import ConfigFileReaderFactory
3
+ from metripy.Application.Config.Config import Config
4
+ from metripy.Application.Config.File.ConfigFileReaderFactory import \
5
+ ConfigFileReaderFactory
5
6
 
6
7
 
7
8
  class Parser:
8
9
  def parse(self, argv: list[str]) -> Config:
9
10
  config = Config()
10
11
 
11
- if argv[0] == "codemetrics.py" or argv[0] == "codemetrics":
12
- # 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
13
14
  pass
14
15
  argv.pop(0)
15
16
 
@@ -1,5 +1,5 @@
1
- from Application.Config.GitConfig import GitConfig
2
- from Application.Config.ReportConfig import ReportConfig
1
+ from metripy.Application.Config.GitConfig import GitConfig
2
+ from metripy.Application.Config.ReportConfig import ReportConfig
3
3
 
4
4
 
5
5
  class ProjectConfig:
@@ -1,6 +1,6 @@
1
1
  from typing import Self
2
2
 
3
- from Component.Output.CliOutput import CliOutput
3
+ from metripy.Component.Output.CliOutput import CliOutput
4
4
 
5
5
 
6
6
  class Debugger:
@@ -1,6 +1,6 @@
1
1
  import os
2
2
 
3
- from Application.Config.ProjectConfig import ProjectConfig
3
+ from metripy.Application.Config.ProjectConfig import ProjectConfig
4
4
 
5
5
 
6
6
  class Finder:
@@ -1,4 +1,4 @@
1
- from Component.Output.CliOutput import CliOutput
1
+ from metripy.Component.Output.CliOutput import CliOutput
2
2
 
3
3
 
4
4
  class ProgressBar:
@@ -1,8 +1,8 @@
1
1
  import json
2
2
  import os
3
3
 
4
- from Dependency.Composer.Packegist import Packegist
5
- from Dependency.Dependency import Dependency
4
+ from metripy.Dependency.Composer.Packegist import Packegist
5
+ from metripy.Dependency.Dependency import Dependency
6
6
 
7
7
 
8
8
  class Composer:
@@ -3,7 +3,7 @@ import re
3
3
  import requests
4
4
  from packaging import version
5
5
 
6
- from Dependency.Dependency import Dependency
6
+ from metripy.Dependency.Dependency import Dependency
7
7
 
8
8
 
9
9
  class Packegist:
@@ -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
@@ -1,8 +1,8 @@
1
1
  import json
2
2
  import os
3
3
 
4
- from Dependency.Dependency import Dependency
5
- from Dependency.Npm.NpmOrg import NpmOrg
4
+ from metripy.Dependency.Dependency import Dependency
5
+ from metripy.Dependency.Npm.NpmOrg import NpmOrg
6
6
 
7
7
 
8
8
  class Npm:
@@ -1,6 +1,6 @@
1
1
  import requests
2
2
 
3
- from Dependency.Dependency import Dependency
3
+ from metripy.Dependency.Dependency import Dependency
4
4
 
5
5
 
6
6
  class NpmOrg:
@@ -0,0 +1,60 @@
1
+ import os
2
+ import re
3
+
4
+ import toml
5
+
6
+ from metripy.Dependency.Dependency import Dependency
7
+ from metripy.Dependency.Pip.PyPi import PyPi
8
+
9
+
10
+ class Pip:
11
+ def get_dependencies(self, path: str) -> list[Dependency]:
12
+ try:
13
+ requirements = self.get_from_requirements_txt(path)
14
+ except FileNotFoundError:
15
+ requirements = self.get_from_pyproject_toml(path)
16
+
17
+ pypi = PyPi()
18
+ packages = []
19
+ for dependency in requirements:
20
+ package = pypi.get_info(dependency)
21
+ packages.append(package)
22
+
23
+ return [item for item in packages if item is not None]
24
+
25
+ def get_from_requirements_txt(self, path: str) -> list[Dependency]:
26
+ with open(os.path.join(path, "requirements.txt"), "r") as file:
27
+ lines = file.readlines()
28
+ return self._parse_dependencies(lines)
29
+
30
+ return []
31
+
32
+ def get_from_pyproject_toml(self, path: str) -> list[Dependency]:
33
+ with open(os.path.join(path, "pyproject.toml"), "r") as f:
34
+ data = toml.load(f)
35
+
36
+ # For PEP 621 / setuptools projects
37
+ if "project" in data:
38
+ deps = data["project"].get("dependencies", [])
39
+ return self._parse_dependencies(deps)
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
+ )
59
+
60
+ return dependencies
@@ -1,6 +1,6 @@
1
1
  import requests
2
2
 
3
- from Dependency.Dependency import Dependency
3
+ from metripy.Dependency.Dependency import Dependency
4
4
 
5
5
 
6
6
  class PyPi:
@@ -3,8 +3,8 @@ from datetime import datetime
3
3
 
4
4
  from git import Repo
5
5
 
6
- from Application.Config.GitConfig import GitConfig
7
- from Metric.Git.GitMetrics import GitMetrics
6
+ from metripy.Application.Config.GitConfig import GitConfig
7
+ from metripy.Metric.Git.GitMetrics import GitMetrics
8
8
 
9
9
 
10
10
  class GitAnalyzer:
@@ -1,7 +1,7 @@
1
1
  from abc import ABC, abstractmethod
2
2
 
3
- from Metric.Code.FileMetrics import FileMetrics
4
- from Tree.ModuleNode import ModuleNode
3
+ from metripy.Metric.Code.FileMetrics import FileMetrics
4
+ from metripy.Tree.ModuleNode import ModuleNode
5
5
 
6
6
 
7
7
  class AbstractLangAnalyzer(ABC):
@@ -3,15 +3,15 @@ from pathlib import Path
3
3
 
4
4
  import lizard
5
5
 
6
- from Component.Output.ProgressBar import ProgressBar
7
- from LangAnalyzer.AbstractLangAnalyzer import AbstractLangAnalyzer
8
- from LangAnalyzer.Php.PhpBasicAstParser import PhpBasicAstParser
9
- from LangAnalyzer.Php.PhpBasicLocAnalyzer import PhpBasicLocAnalyzer
10
- from LangAnalyzer.Php.PhpHalSteadAnalyzer import PhpHalSteadAnalyzer
11
- from Metric.Code.FileMetrics import FileMetrics
12
- from Tree.ClassNode import ClassNode
13
- from Tree.FunctionNode import FunctionNode
14
- from Tree.ModuleNode import ModuleNode
6
+ from metripy.Component.Output.ProgressBar import ProgressBar
7
+ from metripy.LangAnalyzer.AbstractLangAnalyzer import AbstractLangAnalyzer
8
+ from metripy.LangAnalyzer.Php.PhpBasicAstParser import PhpBasicAstParser
9
+ from metripy.LangAnalyzer.Php.PhpBasicLocAnalyzer import PhpBasicLocAnalyzer
10
+ from metripy.LangAnalyzer.Php.PhpHalSteadAnalyzer import PhpHalSteadAnalyzer
11
+ from metripy.Metric.Code.FileMetrics import FileMetrics
12
+ from metripy.Tree.ClassNode import ClassNode
13
+ from metripy.Tree.FunctionNode import FunctionNode
14
+ from metripy.Tree.ModuleNode import ModuleNode
15
15
 
16
16
 
17
17
  class PhpAnalyzer(AbstractLangAnalyzer):
@@ -131,7 +131,7 @@ class PhpAnalyzer(AbstractLangAnalyzer):
131
131
 
132
132
  code_lines = code.split("\n")
133
133
  for func_name, function_node in functions.items():
134
- lines = code_lines[function_node.lineno : function_node.line_end]
134
+ lines = code_lines[function_node.lineno:function_node.line_end]
135
135
  function_metrics = self.halstead_analyzer.calculate_halstead_metrics(
136
136
  "\n".join(lines)
137
137
  )
@@ -1,4 +1,4 @@
1
- from LangAnalyzer.Generic.HalSteadAnalyzer import HalSteadAnalyzer
1
+ from metripy.LangAnalyzer.Generic.HalSteadAnalyzer import HalSteadAnalyzer
2
2
 
3
3
 
4
4
  class PhpHalSteadAnalyzer:
@@ -3,12 +3,12 @@ from radon.metrics import Halstead, HalsteadReport, h_visit, mi_visit
3
3
  from radon.raw import analyze
4
4
  from radon.visitors import Class, Function
5
5
 
6
- from Component.Output.ProgressBar import ProgressBar
7
- from LangAnalyzer.AbstractLangAnalyzer import AbstractLangAnalyzer
8
- from Metric.Code.FileMetrics import FileMetrics
9
- from Tree.ClassNode import ClassNode
10
- from Tree.FunctionNode import FunctionNode
11
- from Tree.ModuleNode import ModuleNode
6
+ from metripy.Component.Output.ProgressBar import ProgressBar
7
+ from metripy.LangAnalyzer.AbstractLangAnalyzer import AbstractLangAnalyzer
8
+ from metripy.Metric.Code.FileMetrics import FileMetrics
9
+ from metripy.Tree.ClassNode import ClassNode
10
+ from metripy.Tree.FunctionNode import FunctionNode
11
+ from metripy.Tree.ModuleNode import ModuleNode
12
12
 
13
13
 
14
14
  class PythonAnalyzer(AbstractLangAnalyzer):
@@ -2,21 +2,19 @@ import math
2
2
 
3
3
  import lizard
4
4
 
5
- from Component.Output.ProgressBar import ProgressBar
6
- from LangAnalyzer.AbstractLangAnalyzer import AbstractLangAnalyzer
7
- from LangAnalyzer.Typescript.TypescriptAstParser import TypescriptAstParser
8
- from LangAnalyzer.Typescript.TypescriptBasicComplexityAnalyzer import (
9
- TypescriptBasicComplexityAnalzyer,
10
- )
11
- from LangAnalyzer.Typescript.TypescriptBasicLocAnalyzer import (
12
- TypescriptBasicLocAnalyzer,
13
- )
14
- from LangAnalyzer.Typescript.TypescriptHalSteadAnalyzer import (
15
- TypeScriptHalSteadAnalyzer,
16
- )
17
- from Tree.ClassNode import ClassNode
18
- from Tree.FunctionNode import FunctionNode
19
- from Tree.ModuleNode import ModuleNode
5
+ from metripy.Component.Output.ProgressBar import ProgressBar
6
+ from metripy.LangAnalyzer.AbstractLangAnalyzer import AbstractLangAnalyzer
7
+ from metripy.LangAnalyzer.Typescript.TypescriptAstParser import \
8
+ TypescriptAstParser
9
+ from metripy.LangAnalyzer.Typescript.TypescriptBasicComplexityAnalyzer import \
10
+ TypescriptBasicComplexityAnalzyer
11
+ from metripy.LangAnalyzer.Typescript.TypescriptBasicLocAnalyzer import \
12
+ TypescriptBasicLocAnalyzer
13
+ from metripy.LangAnalyzer.Typescript.TypescriptHalSteadAnalyzer import \
14
+ TypeScriptHalSteadAnalyzer
15
+ from metripy.Tree.ClassNode import ClassNode
16
+ from metripy.Tree.FunctionNode import FunctionNode
17
+ from metripy.Tree.ModuleNode import ModuleNode
20
18
 
21
19
 
22
20
  class TypescriptAnalyzer(AbstractLangAnalyzer):
@@ -148,7 +146,7 @@ class TypescriptAnalyzer(AbstractLangAnalyzer):
148
146
 
149
147
  code_lines = code.split("\n")
150
148
  for func_name, function_node in functions.items():
151
- lines = code_lines[function_node.lineno : function_node.line_end]
149
+ lines = code_lines[function_node.lineno:function_node.line_end]
152
150
  function_metrics = self.halstead_analyzer.calculate_halstead_metrics(
153
151
  "\n".join(lines)
154
152
  )
@@ -8,7 +8,7 @@ class TypescriptAstParser:
8
8
  self.parser = get_parser("typescript")
9
9
 
10
10
  def _get_node_text(self, code: str, node) -> str:
11
- return code[node.start_byte : node.end_byte].decode("utf-8")
11
+ return code[node.start_byte:node.end_byte].decode("utf-8")
12
12
 
13
13
  def extract_structure(self, code: str) -> dict:
14
14
  tree = self.parser.parse(bytes(code, "utf8"))
@@ -71,18 +71,18 @@ class TypescriptBasicComplexityAnalzyer:
71
71
  |
72
72
  (
73
73
  (export\s+)?(async\s+)?function\s+{re.escape(function_name)}\s*
74
- \(\s*.*?\s*\)\s*\{{
74
+ \(\s*.*?\s*\)\s*\{{
75
75
  )
76
76
  |
77
77
  (
78
78
  (?:public|private|protected)?\s*
79
79
  (?:static\s+)?(?:async\s+)?{re.escape(function_name)}\s*
80
80
  (<[^>]+>)?\s*\(\s*.*?\s*\)\s*
81
- (:\s*[^\{{]+)?\s*\{{
81
+ (:\s*[^\{{]+)?\s*\{{
82
82
  )
83
83
  |
84
84
  (
85
- {re.escape(function_name)}\s*\(\s*.*?\s*\)\s*\{{
85
+ {re.escape(function_name)}\s*\(\s*.*?\s*\)\s*\{{
86
86
  )
87
87
  """,
88
88
  re.MULTILINE | re.DOTALL | re.VERBOSE,
@@ -1,4 +1,4 @@
1
- from LangAnalyzer.Generic.HalSteadAnalyzer import HalSteadAnalyzer
1
+ from metripy.LangAnalyzer.Generic.HalSteadAnalyzer import HalSteadAnalyzer
2
2
 
3
3
 
4
4
  class TypeScriptHalSteadAnalyzer:
@@ -1,4 +1,4 @@
1
- from Metric.Code.SegmentedMetrics import SegmentedMetrics
1
+ from metripy.Metric.Code.SegmentedMetrics import SegmentedMetrics
2
2
 
3
3
 
4
4
  class AggregatedMetrics:
@@ -1,5 +1,5 @@
1
- from Tree.ClassNode import ClassNode
2
- from Tree.FunctionNode import FunctionNode
1
+ from metripy.Tree.ClassNode import ClassNode
2
+ from metripy.Tree.FunctionNode import FunctionNode
3
3
 
4
4
 
5
5
  class FileMetrics:
@@ -1,5 +1,5 @@
1
- from Tree.ClassNode import ClassNode
2
- from Tree.FunctionNode import FunctionNode
1
+ from metripy.Tree.ClassNode import ClassNode
2
+ from metripy.Tree.FunctionNode import FunctionNode
3
3
 
4
4
 
5
5
  class ModuleMetrics:
@@ -1,4 +1,4 @@
1
- from Metric.FileTree.FileTree import FileTree
1
+ from metripy.Metric.FileTree.FileTree import FileTree
2
2
 
3
3
 
4
4
  class FileTreeParser:
@@ -1,6 +1,6 @@
1
- from Metric.Git.GitCodeHotspot import GitCodeHotspot
2
- from Metric.Git.GitContributor import GitContributor
3
- from Metric.Git.GitKnowledgeSilo import GitKnowledgeSilo
1
+ from metripy.Metric.Git.GitCodeHotspot import GitCodeHotspot
2
+ from metripy.Metric.Git.GitContributor import GitContributor
3
+ from metripy.Metric.Git.GitKnowledgeSilo import GitKnowledgeSilo
4
4
 
5
5
 
6
6
  class GitMetrics:
@@ -1,8 +1,9 @@
1
- from Dependency.Dependency import Dependency
2
- from Metric.Code.AggregatedMetrics import AggregatedMetrics
3
- from Metric.Code.FileMetrics import FileMetrics
4
- from Metric.Code.SegmentedMetrics import SegmentedMetrics
5
- from Metric.Git.GitMetrics import GitMetrics
1
+ from metripy.Dependency.Dependency import Dependency
2
+ from metripy.Metric.Code.AggregatedMetrics import AggregatedMetrics
3
+ from metripy.Metric.Code.FileMetrics import FileMetrics
4
+ from metripy.Metric.Code.SegmentedMetrics import SegmentedMetrics
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
@@ -1,6 +1,6 @@
1
- from Application.Config.Config import Config
2
- from Component.Output.CliOutput import CliOutput
3
- from Metric.ProjectMetrics import ProjectMetrics
1
+ from metripy.Application.Config.Config import Config
2
+ from metripy.Component.Output.CliOutput import CliOutput
3
+ from metripy.Metric.ProjectMetrics import ProjectMetrics
4
4
 
5
5
 
6
6
  class Reporter:
@@ -5,11 +5,12 @@ from datetime import datetime
5
5
 
6
6
  from py_template_engine import TemplateEngine
7
7
 
8
- from Application.Config.ReportConfig import ReportConfig
9
- from Component.Output.CliOutput import CliOutput
10
- from Metric.FileTree.FileTreeParser import FileTreeParser
11
- from Metric.ProjectMetrics import ProjectMetrics
12
- from Report.ReporterInterface import ReporterInterface
8
+ from metripy.Application.Config.ReportConfig import ReportConfig
9
+ from metripy.Component.Output.CliOutput import CliOutput
10
+ from metripy.Metric.FileTree.FileTreeParser import FileTreeParser
11
+ from metripy.Metric.ProjectMetrics import ProjectMetrics
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
  ),
@@ -1,7 +1,8 @@
1
- from Report.ReporterInterface import ReporterInterface
2
1
  import json
3
2
  import os
4
3
 
4
+ from metripy.Report.ReporterInterface import ReporterInterface
5
+
5
6
 
6
7
  class AbstractJsonReporter(ReporterInterface):
7
8
  def put_data(self, data: dict) -> None:
@@ -1,5 +1,5 @@
1
- from Report.Json.AbstractJsonReporter import AbstractJsonReporter
2
- from Metric.ProjectMetrics import ProjectMetrics
1
+ from metripy.Metric.ProjectMetrics import ProjectMetrics
2
+ from metripy.Report.Json.AbstractJsonReporter import AbstractJsonReporter
3
3
 
4
4
 
5
5
  class GitJsonReporter(AbstractJsonReporter):
@@ -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>")
@@ -0,0 +1,13 @@
1
+ from metripy.Application.Config.Config import Config
2
+ from metripy.Component.Output.CliOutput import CliOutput
3
+ from metripy.Metric.ProjectMetrics import ProjectMetrics
4
+ from metripy.Report.Json.AbstractJsonReporter import AbstractJsonReporter
5
+
6
+ class JsonReporter(AbstractJsonReporter):
7
+ def __init__(self, config: Config, output: CliOutput):
8
+ self.config = config
9
+ self.output = output
10
+
11
+ def generate(self, metrics: ProjectMetrics):
12
+ self.put_data(metrics.to_dict())
13
+ self.output.writeln(f"<success>Create json report in {self.config.path}</success>")
@@ -1,8 +1,9 @@
1
- from Application.Config.ReportConfig import ReportConfig
2
- from Component.Output.CliOutput import CliOutput
3
- from Report import ReporterInterface
4
- from Report.Html.Reporter import Reporter as HtmlReporter
5
- from Report.Json.GitJsonReporter import GitJsonReporter
1
+ from metripy.Application.Config.ReportConfig import ReportConfig
2
+ from metripy.Component.Output.CliOutput import CliOutput
3
+ from metripy.Report import ReporterInterface
4
+ from metripy.Report.Html.Reporter import Reporter as HtmlReporter
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,8 +1,8 @@
1
1
  from abc import ABC, abstractmethod
2
2
 
3
- from Metric.ProjectMetrics import ProjectMetrics
4
- from Application.Config.ReportConfig import ReportConfig
5
- from Component.Output.CliOutput import CliOutput
3
+ from metripy.Application.Config.ReportConfig import ReportConfig
4
+ from metripy.Component.Output.CliOutput import CliOutput
5
+ from metripy.Metric.ProjectMetrics import ProjectMetrics
6
6
 
7
7
 
8
8
  class ReporterInterface(ABC):
@@ -1,4 +1,4 @@
1
- from Tree.FunctionNode import FunctionNode
1
+ from metripy.Tree.FunctionNode import FunctionNode
2
2
 
3
3
 
4
4
  class ClassNode:
@@ -1,5 +1,5 @@
1
- from Tree.ClassNode import ClassNode
2
- from Tree.FunctionNode import FunctionNode
1
+ from metripy.Tree.ClassNode import ClassNode
2
+ from metripy.Tree.FunctionNode import FunctionNode
3
3
 
4
4
 
5
5
  class ModuleNode:
@@ -2,7 +2,7 @@
2
2
  """main module"""
3
3
  import sys
4
4
 
5
- from Application.Application import Application
5
+ from metripy.Application.Application import Application
6
6
 
7
7
 
8
8
  def main():
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: metripy
3
- Version: 0.2.5
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
@@ -34,9 +34,10 @@ Requires-Dist: black>=22.0.0; extra == "dev"
34
34
  Requires-Dist: flake8>=5.0.0; extra == "dev"
35
35
  Requires-Dist: mypy>=0.991; extra == "dev"
36
36
  Requires-Dist: poethepoet==0.37.0; extra == "dev"
37
+ Requires-Dist: isort==7.0.0; extra == "dev"
37
38
  Dynamic: license-file
38
39
 
39
- # Codemetrics
40
+ # Metripy
40
41
  A multilanguage, multi project code metrics analysis tool.
41
42
 
42
43
  # Languages
@@ -82,10 +83,10 @@ Sample configuraiton:
82
83
  ```json
83
84
  {
84
85
  "configs": {
85
- "funny codemetrics": {
86
+ "metripy": {
86
87
  "base_path": "./", // base path to look at
87
88
  "includes": [
88
- "src/" // paths to include from the base path on
89
+ "metripy/" // paths to include from the base path on
89
90
  ],
90
91
  "excludes": [
91
92
  "__pycache__" // exclude patterns of paths / files
@@ -101,8 +102,8 @@ Sample configuraiton:
101
102
  "pip": true,
102
103
  // looks for base_path/requirements.txt or base_path/pyproject.toml and analyzes dependencies - for python projects
103
104
  "reports": {
104
- "html": "./build/report/codemetrics", // report should be put into this directory
105
- "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
106
107
  // more types of reports TBA
107
108
  }
108
109
  },
@@ -110,3 +111,20 @@ Sample configuraiton:
110
111
  }
111
112
  }
112
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
+ ```
@@ -0,0 +1,66 @@
1
+ metripy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ metripy/metripy.py,sha256=Iiggyf5cMv3xoJyyec6MpqPLb0afYnPyOYY26oiq6ro,266
3
+ metripy/Application/Analyzer.py,sha256=QoKk7iKvgYp5AwvXnsrEwAxAqWFXNhdn9HHJDkzvj20,4043
4
+ metripy/Application/Application.py,sha256=mmvb2Af3AsfcDVwhf5LB5xVWxE5XmKSSaW_IY7ur2Qw,1971
5
+ metripy/Application/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ metripy/Application/Config/Config.py,sha256=VyBBYtbVNkrdevxkIGlASSCgK7pmq2WLW6DVKUMb6B4,353
7
+ metripy/Application/Config/GitConfig.py,sha256=4y676GYv-FH6QyLxh6IQn64gUG9xOQciMgkXH9pJtb4,220
8
+ metripy/Application/Config/Parser.py,sha256=ej3wT8AYtAVg-3q59FtkFb_-pxfy7Hvn4YswAVL8M4A,892
9
+ metripy/Application/Config/ProjectConfig.py,sha256=N2xPkc10NF3mHywR36vpxsrcdJyw-VTFzbwQpLq5uHw,932
10
+ metripy/Application/Config/ReportConfig.py,sha256=Vh3S1n2nyH5YNmt8JrfGRTcmYZuqLMxyFnFF5mmxu_4,259
11
+ metripy/Application/Config/File/ConfigFileReaderFactory.py,sha256=K6p5x5TgF6I0acfq3dnU_wKWRWMD-e1EEa0_nrf7t8g,925
12
+ metripy/Application/Config/File/ConfigFileReaderInterface.py,sha256=atBdkvofs4HNI53ja_Knpi99N1H2NVKg16ohYFlH2bw,281
13
+ metripy/Application/Config/File/JsonConfigFileReader.py,sha256=yUlrbqPU802z8Lbo6oGD1Q_bDT1s_4ODRShrneTavAg,2808
14
+ metripy/Component/Debug/Debugger.py,sha256=LhkHzUGNSEPvIvcjZJJob5Fjg5NQhk7Rs43y1Bkc7hw,423
15
+ metripy/Component/File/Finder.py,sha256=1vP3KD98zxBuIShNlfCOVVLbjOQPLJnrIsUvLzxnVnM,1399
16
+ metripy/Component/Output/CliOutput.py,sha256=XJ5vJa7jxoukk4fRuj1UVV7GNkkZx-4Jb_Pl7ZYOSFk,1197
17
+ metripy/Component/Output/ProgressBar.py,sha256=PmYQYwINXn9sYO0FKqT8tF-FaFLrPko-lJfi6jxbNsA,725
18
+ metripy/Dependency/Dependency.py,sha256=Y2j3xIMvPStzaW_TmsNx122gUxTYTnOGuMIgoUgVLVs,1482
19
+ metripy/Dependency/Composer/Composer.py,sha256=tOVo8-NJfn0bRK-K4-hhq394tfigOtE6-5ZXOPTb_jw,1033
20
+ metripy/Dependency/Composer/Packegist.py,sha256=ioeIwNg6Yhz0bk13UpB7saq4eqB0-3Zy9PdfcE3CIbA,1980
21
+ metripy/Dependency/Npm/Npm.py,sha256=OB05MZJ312dRw909Pj4Np4bqHQ5oVOylqnzdfXdRvhM,975
22
+ metripy/Dependency/Npm/NpmOrg.py,sha256=9igY0dZRP2L36jcCsn8I8WgfxjWhJ2FShcIV9ph-Zfs,1551
23
+ metripy/Dependency/Pip/Pip.py,sha256=b-XkyDGnLISfAchsD9Lo-M03rUZogGlvkhntC2h7WoI,1911
24
+ metripy/Dependency/Pip/PyPi.py,sha256=Hqpk5rUw-sN23tgWVUaYMuLN43BR8LdbmNJzkKq9gEo,1612
25
+ metripy/Git/GitAnalyzer.py,sha256=k1396AKkZHlCHZZTtlBHMNO73Cnhcte2ageXJo4ObVY,3071
26
+ metripy/LangAnalyzer/AbstractLangAnalyzer.py,sha256=Wa7ucL7Wy6J8f13GyCOjRKYFgPuJPuZjE8t24fDUf2U,1896
27
+ metripy/LangAnalyzer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
+ metripy/LangAnalyzer/Generic/HalSteadAnalyzer.py,sha256=z8h3V7mud5NnzQ67I9G3YhTFKHjO6Z-e_ida2d32YZ4,1845
29
+ metripy/LangAnalyzer/Generic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
+ metripy/LangAnalyzer/Php/PhpAnalyzer.py,sha256=g4Kj3IjL0BgBUY-Ons1MitdandglK-26R324b9AFBJs,7449
31
+ metripy/LangAnalyzer/Php/PhpBasicAstParser.py,sha256=T717e7hM67HBOZ7mvl7Jr4RkCF-Hq-sUMzk__UTheeU,1874
32
+ metripy/LangAnalyzer/Php/PhpBasicLocAnalyzer.py,sha256=2Vt3pbU0BEy2p8em3ZW_qOe9eGigtpZzVoEhe11S2O8,6229
33
+ metripy/LangAnalyzer/Php/PhpHalSteadAnalyzer.py,sha256=XgEo1dXSpIYWBWt9wEQxigpNdLWs-BteX2U2lVLVpl8,1037
34
+ metripy/LangAnalyzer/Python/PythonAnalyzer.py,sha256=sUNLtFge_1zXqBa5qlaaghxPunaSHQAHPOoS1U3XtQc,5043
35
+ metripy/LangAnalyzer/Typescript/TypescriptAnalyzer.py,sha256=eURSa3EYWP8DBJugcM81ctw3H-wFPzp8U7Gup35AhJM,8106
36
+ metripy/LangAnalyzer/Typescript/TypescriptAstParser.py,sha256=6kEw3tm9_eIOXkBY_V5YCFXHdb_PI-1TDEELrInPSKE,2917
37
+ metripy/LangAnalyzer/Typescript/TypescriptBasicComplexityAnalyzer.py,sha256=abQXNPywSoplozwwV1qm8tRKyPkCAhxBF8gHigECeZ0,3797
38
+ metripy/LangAnalyzer/Typescript/TypescriptBasicLocAnalyzer.py,sha256=hxNqVGDUBb0Dy4cvQFTqfz5cCJTQ8B4uWu9hBnzSO2Y,2336
39
+ metripy/LangAnalyzer/Typescript/TypescriptHalSteadAnalyzer.py,sha256=yOW_55R4PcTNA2BffCiugqkBH1ONuYkZCFo2No4hz0w,1278
40
+ metripy/Metric/ProjectMetrics.py,sha256=YE6-C4kdVyMBqrzTXmPl9HSDk0wqEeOKYGziIYI5Lw0,2735
41
+ metripy/Metric/Code/AggregatedMetrics.py,sha256=fLAuvM6f_ToFICQMsxZ8azNv2OTBQvbzETCJ8vA9SQY,1559
42
+ metripy/Metric/Code/FileMetrics.py,sha256=BnAhjHeJawBV8X4EOLtJ4-aL-VmfKj4AGXmEoRV-gQE,1150
43
+ metripy/Metric/Code/ModuleMetrics.py,sha256=J0eKYFm_m3lIJUjU0YkoADPs6HvNxHkJXHr69QTKXl8,1185
44
+ metripy/Metric/Code/SegmentedMetrics.py,sha256=DqXZsagrz5yicAECXGO8e6xvhY9SivkhJvQKH9TKtaw,1730
45
+ metripy/Metric/FileTree/FileTree.py,sha256=X5KeQ26lCEcUcYoa8q6ITO0kpgqphLmXWlG-NGeXpX0,467
46
+ metripy/Metric/FileTree/FileTreeParser.py,sha256=GUnSX1RZ--nB6srYSy-NZm1VZh34Bgnq2yuAvfpmlUM,1291
47
+ metripy/Metric/Git/GitCodeHotspot.py,sha256=zdqmXZu9cELpJ7-KGTW3tbmD2so2R6c0w1gYg2OU1jc,1291
48
+ metripy/Metric/Git/GitContributor.py,sha256=Sn3Rmds7tr1H6CsR8bJ2cfuwG7tRj0vVadD28dKa6OE,1172
49
+ metripy/Metric/Git/GitKnowledgeSilo.py,sha256=arla_KR2zyfw9O5QPDhxBrkc-bfQ-pvQuA6GUgv2c44,946
50
+ metripy/Metric/Git/GitMetrics.py,sha256=k-MOdHaT6nOgHjQlRjjhrjIk9UjKiPMNKfjNP2WcWjM,5769
51
+ metripy/Report/ReporterFactory.py,sha256=LzB2rMGaTUyEHQ0R3wy4MC8C3yVds16rpDe2TGExFoE,965
52
+ metripy/Report/ReporterInterface.py,sha256=OZEE3SXpTKNOKQBzPytqxqViUFzPhlBUjkBTMlib0qE,543
53
+ metripy/Report/Csv/Reporter.py,sha256=rC52vfJYavB_9yZ3-QA7aRF0Ez34lkiBOpw2mWll2m8,431
54
+ metripy/Report/Html/Reporter.py,sha256=ePKXp1ZEwRSb5s2a0kjSobtiYDkr0YZ2SYcDeF2lLL4,8457
55
+ metripy/Report/Json/AbstractJsonReporter.py,sha256=yqpBOO6MAN2HdhwoWOZ7Ler38WbV8DcG5g2oASXe-i8,343
56
+ metripy/Report/Json/GitJsonReporter.py,sha256=-kirTcruclxGnbEAMdE3waPO8jLoIaFCphJiKkFkQ9M,946
57
+ metripy/Report/Json/JsonReporter.py,sha256=To9sr2OJ39OqaAO1ynhy1fm4SK8Pa69Ubaf-YV-uRns,584
58
+ metripy/Tree/ClassNode.py,sha256=uh2JJ3s9H6sCcj_ppElODUvvA525oHVnuhrW-ktzMj8,916
59
+ metripy/Tree/FunctionNode.py,sha256=c2T78uGVkNRF_c2jCVmtfAwNFeY3MgASbUApROAsl3c,1520
60
+ metripy/Tree/ModuleNode.py,sha256=YHlkAJKWWjy1oAhg7IdrvYnTOxpBYnq_VJS_ykey5_Y,1238
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,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ metripy = metripy.metripy:main
@@ -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
@@ -0,0 +1 @@
1
+ metripy
@@ -1,66 +0,0 @@
1
- metripy-0.2.5.dist-info/licenses/LICENSE,sha256=RQUMdlYUkqBhJgf7iIlzqrlaYz8VGr6KAn60wkv3FzE,1067
2
- src/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- src/codemetrics.py,sha256=zBlIveTZax-kKi20CFFYLKYrpBw1MPzdFXO8NdKqzso,258
4
- src/Application/Analyzer.py,sha256=e4UQnLXc25F8rBQiHC441DhTabWmFdMZt0EdEgbcO-0,3909
5
- src/Application/Application.py,sha256=A4ytSzZGaNvs9MQ4egYbTzikkcNXRR7Oayipwa-9N-8,1915
6
- src/Application/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- src/Application/Config/Config.py,sha256=rEO3p57Rf0JCuBlNj16o3i1XoonZYLOdHUvyh09nKXc,345
8
- src/Application/Config/GitConfig.py,sha256=4y676GYv-FH6QyLxh6IQn64gUG9xOQciMgkXH9pJtb4,220
9
- src/Application/Config/Parser.py,sha256=gzzpciFtGTOwuoHCOX1GQXecYQT6ndwM0DFDAtSlHrM,882
10
- src/Application/Config/ProjectConfig.py,sha256=kB5Zl1PdOBYFuTuQkSuc4c2zHl2trNJGu5S-t0SPDbw,916
11
- src/Application/Config/ReportConfig.py,sha256=Vh3S1n2nyH5YNmt8JrfGRTcmYZuqLMxyFnFF5mmxu_4,259
12
- src/Application/Config/File/ConfigFileReaderFactory.py,sha256=0WGj8cVD5Bd6KWjA1tthD0iHcFiA9arjMGMzZi1_-lg,897
13
- src/Application/Config/File/ConfigFileReaderInterface.py,sha256=vJPJdob3zMCYlPT2yNZZnqw_KGbTwWepWfUFiNA-jRs,273
14
- src/Application/Config/File/JsonConfigFileReader.py,sha256=TEAdCzeGu3I1GD590iMatZZkfvRtyHcy68HcSNK3BQk,2762
15
- src/Component/Debug/Debugger.py,sha256=puvmjX-AenkXcpHJZuXL2eW0Sq4OEZvDj9diAdyiwZ4,415
16
- src/Component/File/Finder.py,sha256=nLJqQsnmOkbX9YuuiA0LWfAQEPsfw1hoteZEfAbQtT0,1391
17
- src/Component/Output/CliOutput.py,sha256=XJ5vJa7jxoukk4fRuj1UVV7GNkkZx-4Jb_Pl7ZYOSFk,1197
18
- src/Component/Output/ProgressBar.py,sha256=CGt6RfLukbDdfMgVvSkDfOIqEuFBh6LFvmYid2A1IBs,717
19
- src/Dependency/Dependency.py,sha256=6YSuNPEAbJY5MZ_8ZwMyppnWA_j84dwKx_hzm0eYmYc,1002
20
- src/Dependency/Composer/Composer.py,sha256=iHNHsGmNOLSOjwUywuzsVqYX2kKPcVA63sUhMYDdzl8,1017
21
- src/Dependency/Composer/Packegist.py,sha256=frroQwCJjFMonnrs9AueJW3OhTD1IOB-e96tTnZ4YFw,1972
22
- src/Dependency/Npm/Npm.py,sha256=nwN_LU0B7ukg_E63S3AdnHsGmb521FbUsCBZk9GeyTw,959
23
- src/Dependency/Npm/NpmOrg.py,sha256=Bp9LUluc_lbqHDHO8O5MNtaIODdN1hYtsmw-XbqjnXM,1543
24
- src/Dependency/Pip/Pip.py,sha256=MfuUbV86yYKyHngF5Qn2A-6YsQdcf_3gQu_2tKQ9ink,2302
25
- src/Dependency/Pip/PyPi.py,sha256=cCHU8WEeal9EXPuCfrwWzrj4j6yo2BFpBG4TqGVwEow,1604
26
- src/Git/GitAnalyzer.py,sha256=DLlQUe3xXRKFG0H7oQjWsbKHGrCyieo3OGwkrF30Rps,3055
27
- src/LangAnalyzer/AbstractLangAnalyzer.py,sha256=xT12UhRfJ0VeV2yXvNPCXYLIegGG2ps_53pA2ztcCLc,1880
28
- src/LangAnalyzer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
- src/LangAnalyzer/Generic/HalSteadAnalyzer.py,sha256=z8h3V7mud5NnzQ67I9G3YhTFKHjO6Z-e_ida2d32YZ4,1845
30
- src/LangAnalyzer/Generic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
- src/LangAnalyzer/Php/PhpAnalyzer.py,sha256=j0qorVWBx5tm5c0U5R1XSaNWgRrrVU9bolMrPE43lZI,7379
32
- src/LangAnalyzer/Php/PhpBasicAstParser.py,sha256=T717e7hM67HBOZ7mvl7Jr4RkCF-Hq-sUMzk__UTheeU,1874
33
- src/LangAnalyzer/Php/PhpBasicLocAnalyzer.py,sha256=2Vt3pbU0BEy2p8em3ZW_qOe9eGigtpZzVoEhe11S2O8,6229
34
- src/LangAnalyzer/Php/PhpHalSteadAnalyzer.py,sha256=l6oOqGIss5XHKvKwqqyw4Nu_3v-pRpdlZFIawVIyRCY,1029
35
- src/LangAnalyzer/Python/PythonAnalyzer.py,sha256=s6Y_DxZEn20ljKFLwY0kLyrx9zAMG_fstPJIktLXbCo,4995
36
- src/LangAnalyzer/Typescript/TypescriptAnalyzer.py,sha256=7sdcuniPPBqWvJZEuu4q7MWfpwdPLqyqUOxbSTuBVyM,8039
37
- src/LangAnalyzer/Typescript/TypescriptAstParser.py,sha256=i0AVU1Sx0hJ62eho0wwsUgIRLDJLeAiW_jk_jO8WEKA,2919
38
- src/LangAnalyzer/Typescript/TypescriptBasicComplexityAnalyzer.py,sha256=zEmqN3ha94XrpQwqtwX6VReNaYrNOkwWH-8igzdFEkE,3800
39
- src/LangAnalyzer/Typescript/TypescriptBasicLocAnalyzer.py,sha256=hxNqVGDUBb0Dy4cvQFTqfz5cCJTQ8B4uWu9hBnzSO2Y,2336
40
- src/LangAnalyzer/Typescript/TypescriptHalSteadAnalyzer.py,sha256=b65kNDQaygoHAyG442-mcstYdaj7tlcCuiWslvIj2t0,1270
41
- src/Metric/ProjectMetrics.py,sha256=qciYncQqQEJiSlX5byKq61HCeRVHi7U1cUfF7xH2bcQ,2054
42
- src/Metric/Code/AggregatedMetrics.py,sha256=SDpMFLV-hUXkHKFp3tZuCGySRuNGjW2VNkQq8Eqcl9Q,1551
43
- src/Metric/Code/FileMetrics.py,sha256=NIRRGgmT6eD-cq3DYgwi9vo-v-Eo_cf64eudMu9n6sA,1134
44
- src/Metric/Code/ModuleMetrics.py,sha256=x45xQbDy56_gSYuKrSPi0iWQFRbE9CPlYpho8_ZdW8c,1169
45
- src/Metric/Code/SegmentedMetrics.py,sha256=DqXZsagrz5yicAECXGO8e6xvhY9SivkhJvQKH9TKtaw,1730
46
- src/Metric/FileTree/FileTree.py,sha256=X5KeQ26lCEcUcYoa8q6ITO0kpgqphLmXWlG-NGeXpX0,467
47
- src/Metric/FileTree/FileTreeParser.py,sha256=AyyyajqXqvttxvT20g6damgeq9ExUCBBettv90fRRWw,1283
48
- src/Metric/Git/GitCodeHotspot.py,sha256=zdqmXZu9cELpJ7-KGTW3tbmD2so2R6c0w1gYg2OU1jc,1291
49
- src/Metric/Git/GitContributor.py,sha256=Sn3Rmds7tr1H6CsR8bJ2cfuwG7tRj0vVadD28dKa6OE,1172
50
- src/Metric/Git/GitKnowledgeSilo.py,sha256=arla_KR2zyfw9O5QPDhxBrkc-bfQ-pvQuA6GUgv2c44,946
51
- src/Metric/Git/GitMetrics.py,sha256=5gQi2JHjjafZ3fKgLW0pwa6wTCsEMPXc0m_NND-69WY,5745
52
- src/Report/ReporterFactory.py,sha256=U5wxEuv-Ihi1y7rbVxa1RHaKlZDhCDZJI08iWzTsS7k,857
53
- src/Report/ReporterInterface.py,sha256=7xLrpTuLPnQRI8uZaovx7-VkLWK2mRIxBLSpmaIgpec,519
54
- src/Report/Csv/Reporter.py,sha256=N0VJIayP-gakyqJanuQ9vafbGn7d5JRD1R6vCyAruHg,407
55
- src/Report/Html/Reporter.py,sha256=89eianUFZlhXPSANMHf0yKuMXYhpKwm5Fj-qklUthd8,8598
56
- src/Report/Json/AbstractJsonReporter.py,sha256=ely5RMqRrIV-kZsWc_-_4JfVDKyQlG5dAytBJkJioO0,334
57
- src/Report/Json/GitJsonReporter.py,sha256=c45ubLOXpDfEn-3m5re8vx51uhi-yiQJQ8TVrSY4Lno,834
58
- src/Report/Json/JsonReporter.py,sha256=aPazuX3R1aOpJUDGLG8WDi-7rL_WAN9J_PJ282ftFug,366
59
- src/Tree/ClassNode.py,sha256=_Ci6B72b5WeQBkv77J3phLw3DRpqQlgk32a-cLeo7v8,908
60
- src/Tree/FunctionNode.py,sha256=c2T78uGVkNRF_c2jCVmtfAwNFeY3MgASbUApROAsl3c,1520
61
- src/Tree/ModuleNode.py,sha256=3vrM6ERdh63AGn4Zp06647Fu7KQ3gKenqmjZ72OLWD4,1222
62
- metripy-0.2.5.dist-info/METADATA,sha256=NShjMgB285S_kVIJUeem3QiJ-TxWpdbidfxZRC0C7ew,3841
63
- metripy-0.2.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
64
- metripy-0.2.5.dist-info/entry_points.txt,sha256=G3czqTUzqUsBf_-XbSCVQBp6OIWO9pFjaJa2CATzDks,53
65
- metripy-0.2.5.dist-info/top_level.txt,sha256=74rtVfumQlgAPzR5_2CgYN24MB0XARCg0t-gzk6gTrM,4
66
- metripy-0.2.5.dist-info/RECORD,,
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- codemetrics = src.codemetrics:main
@@ -1 +0,0 @@
1
- src
src/Dependency/Pip/Pip.py DELETED
@@ -1,69 +0,0 @@
1
- import os
2
- import re
3
-
4
- import toml
5
-
6
- from Dependency.Dependency import Dependency
7
- from Dependency.Pip.PyPi import PyPi
8
-
9
-
10
- class Pip:
11
- def get_dependencies(self, path: str) -> list[Dependency]:
12
- try:
13
- requirements = self.get_from_requirements_txt(path)
14
- except FileNotFoundError:
15
- requirements = self.get_from_pyproject_toml(path)
16
-
17
- pypi = PyPi()
18
- packages = []
19
- for dependency in requirements:
20
- package = pypi.get_info(dependency)
21
- packages.append(package)
22
-
23
- return [item for item in packages if item is not None]
24
-
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
- with open(os.path.join(path, "requirements.txt"), "r") as file:
30
- lines = file.readlines()
31
- for line in lines:
32
-
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
41
-
42
- def get_from_pyproject_toml(self, path: str) -> list[Dependency]:
43
- dependencies = []
44
-
45
- with open(os.path.join(path, "pyproject.toml"), "r") as f:
46
- data = toml.load(f)
47
-
48
- # For PEP 621 / setuptools projects
49
- if "project" in data:
50
- 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
65
-
66
-
67
- if __name__ == "__main__":
68
- pip = Pip()
69
- pip.get_dependencies("./")
@@ -1,12 +0,0 @@
1
- from Application.Config.Config import Config
2
- from Component.Output.CliOutput import CliOutput
3
- from Metric.ProjectMetrics import ProjectMetrics
4
-
5
-
6
- class JsonReporter:
7
- def __init__(self, config: Config, output: CliOutput):
8
- self.config = config
9
- self.output = output
10
-
11
- def generate(self, metrics: ProjectMetrics):
12
- raise NotImplementedError
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes