metripy 0.2.5__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.
- metripy-0.2.5.dist-info/METADATA +112 -0
- metripy-0.2.5.dist-info/RECORD +66 -0
- metripy-0.2.5.dist-info/WHEEL +5 -0
- metripy-0.2.5.dist-info/entry_points.txt +2 -0
- metripy-0.2.5.dist-info/licenses/LICENSE +21 -0
- metripy-0.2.5.dist-info/top_level.txt +1 -0
- src/Application/Analyzer.py +105 -0
- src/Application/Application.py +54 -0
- src/Application/Config/Config.py +13 -0
- src/Application/Config/File/ConfigFileReaderFactory.py +22 -0
- src/Application/Config/File/ConfigFileReaderInterface.py +14 -0
- src/Application/Config/File/JsonConfigFileReader.py +81 -0
- src/Application/Config/GitConfig.py +10 -0
- src/Application/Config/Parser.py +30 -0
- src/Application/Config/ProjectConfig.py +27 -0
- src/Application/Config/ReportConfig.py +10 -0
- src/Application/__init__.py +0 -0
- src/Component/Debug/Debugger.py +20 -0
- src/Component/File/Finder.py +37 -0
- src/Component/Output/CliOutput.py +49 -0
- src/Component/Output/ProgressBar.py +27 -0
- src/Dependency/Composer/Composer.py +30 -0
- src/Dependency/Composer/Packegist.py +55 -0
- src/Dependency/Dependency.py +30 -0
- src/Dependency/Npm/Npm.py +30 -0
- src/Dependency/Npm/NpmOrg.py +47 -0
- src/Dependency/Pip/Pip.py +69 -0
- src/Dependency/Pip/PyPi.py +49 -0
- src/Git/GitAnalyzer.py +86 -0
- src/LangAnalyzer/AbstractLangAnalyzer.py +65 -0
- src/LangAnalyzer/Generic/HalSteadAnalyzer.py +58 -0
- src/LangAnalyzer/Generic/__init__.py +0 -0
- src/LangAnalyzer/Php/PhpAnalyzer.py +193 -0
- src/LangAnalyzer/Php/PhpBasicAstParser.py +56 -0
- src/LangAnalyzer/Php/PhpBasicLocAnalyzer.py +174 -0
- src/LangAnalyzer/Php/PhpHalSteadAnalyzer.py +44 -0
- src/LangAnalyzer/Python/PythonAnalyzer.py +129 -0
- src/LangAnalyzer/Typescript/TypescriptAnalyzer.py +210 -0
- src/LangAnalyzer/Typescript/TypescriptAstParser.py +68 -0
- src/LangAnalyzer/Typescript/TypescriptBasicComplexityAnalyzer.py +114 -0
- src/LangAnalyzer/Typescript/TypescriptBasicLocAnalyzer.py +69 -0
- src/LangAnalyzer/Typescript/TypescriptHalSteadAnalyzer.py +55 -0
- src/LangAnalyzer/__init__.py +0 -0
- src/Metric/Code/AggregatedMetrics.py +42 -0
- src/Metric/Code/FileMetrics.py +33 -0
- src/Metric/Code/ModuleMetrics.py +32 -0
- src/Metric/Code/SegmentedMetrics.py +65 -0
- src/Metric/FileTree/FileTree.py +15 -0
- src/Metric/FileTree/FileTreeParser.py +42 -0
- src/Metric/Git/GitCodeHotspot.py +37 -0
- src/Metric/Git/GitContributor.py +37 -0
- src/Metric/Git/GitKnowledgeSilo.py +27 -0
- src/Metric/Git/GitMetrics.py +148 -0
- src/Metric/ProjectMetrics.py +55 -0
- src/Report/Csv/Reporter.py +12 -0
- src/Report/Html/Reporter.py +210 -0
- src/Report/Json/AbstractJsonReporter.py +10 -0
- src/Report/Json/GitJsonReporter.py +21 -0
- src/Report/Json/JsonReporter.py +12 -0
- src/Report/ReporterFactory.py +22 -0
- src/Report/ReporterInterface.py +17 -0
- src/Tree/ClassNode.py +32 -0
- src/Tree/FunctionNode.py +49 -0
- src/Tree/ModuleNode.py +42 -0
- src/__init__.py +0 -0
- src/codemetrics.py +15 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from Report.Json.AbstractJsonReporter import AbstractJsonReporter
|
|
2
|
+
from Metric.ProjectMetrics import ProjectMetrics
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class GitJsonReporter(AbstractJsonReporter):
|
|
6
|
+
def generate(self, metrics: ProjectMetrics) -> None:
|
|
7
|
+
if not metrics.git_metrics:
|
|
8
|
+
self.output.writeln(
|
|
9
|
+
"<error>Wants git json report, but no git metrics</error>"
|
|
10
|
+
)
|
|
11
|
+
return
|
|
12
|
+
|
|
13
|
+
data = {
|
|
14
|
+
"commits_per_month": metrics.git_metrics.get_commit_stats_per_month(),
|
|
15
|
+
"churn_data": metrics.git_metrics.get_churn_per_month(),
|
|
16
|
+
"possible_silos": metrics.git_metrics.get_silos_list()[:10],
|
|
17
|
+
"top_contributors": metrics.git_metrics.get_contributors_list()[:10],
|
|
18
|
+
"top_hotspots": metrics.git_metrics.get_hotspots_list()[:10],
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
self.put_data(data)
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ReporterFactory:
|
|
9
|
+
@staticmethod
|
|
10
|
+
def create(config: ReportConfig, output: CliOutput) -> ReporterInterface:
|
|
11
|
+
if config.type == "html":
|
|
12
|
+
return HtmlReporter(config, output)
|
|
13
|
+
elif config.type == "json":
|
|
14
|
+
raise NotImplementedError
|
|
15
|
+
elif config.type == "csv":
|
|
16
|
+
raise NotImplementedError
|
|
17
|
+
elif config.type == "cli":
|
|
18
|
+
raise NotImplementedError
|
|
19
|
+
elif config.type == "json-git":
|
|
20
|
+
return GitJsonReporter(config, output)
|
|
21
|
+
else:
|
|
22
|
+
raise ValueError(f"Unsupported report type: {config.type}")
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
|
|
3
|
+
from Metric.ProjectMetrics import ProjectMetrics
|
|
4
|
+
from Application.Config.ReportConfig import ReportConfig
|
|
5
|
+
from Component.Output.CliOutput import CliOutput
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ReporterInterface(ABC):
|
|
9
|
+
def __init__(
|
|
10
|
+
self, config: ReportConfig, output: CliOutput, project_name: str = "foobar"
|
|
11
|
+
):
|
|
12
|
+
self.config: ReportConfig = config
|
|
13
|
+
self.output = output
|
|
14
|
+
|
|
15
|
+
@abstractmethod
|
|
16
|
+
def generate(self, metrics: ProjectMetrics) -> None:
|
|
17
|
+
raise NotImplementedError()
|
src/Tree/ClassNode.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from Tree.FunctionNode import FunctionNode
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ClassNode:
|
|
5
|
+
def __init__(
|
|
6
|
+
self,
|
|
7
|
+
full_name: str,
|
|
8
|
+
name: str,
|
|
9
|
+
lineno: int,
|
|
10
|
+
col_offset: int,
|
|
11
|
+
real_complexity: int,
|
|
12
|
+
):
|
|
13
|
+
self.full_name = full_name
|
|
14
|
+
self.name = name
|
|
15
|
+
self.lineno = lineno
|
|
16
|
+
self.col_offset = col_offset
|
|
17
|
+
self.real_complexity = real_complexity
|
|
18
|
+
self.functions: list[FunctionNode] = []
|
|
19
|
+
|
|
20
|
+
def to_dict(self) -> dict:
|
|
21
|
+
"""Convert ClassNode to a dictionary for JSON serialization."""
|
|
22
|
+
return {
|
|
23
|
+
"full_name": self.full_name,
|
|
24
|
+
"name": self.name,
|
|
25
|
+
"lineno": self.lineno,
|
|
26
|
+
"col_offset": self.col_offset,
|
|
27
|
+
"real_complexity": self.real_complexity,
|
|
28
|
+
"functions": [func.to_dict() for func in self.functions],
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
def __dict__(self) -> dict:
|
|
32
|
+
return self.to_dict()
|
src/Tree/FunctionNode.py
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
class FunctionNode:
|
|
2
|
+
def __init__(
|
|
3
|
+
self, full_name: str, name: str, lineno: int, col_offset: int, complexity: int
|
|
4
|
+
):
|
|
5
|
+
self.full_name = full_name
|
|
6
|
+
self.name = name
|
|
7
|
+
self.lineno = lineno
|
|
8
|
+
self.line_end = 0
|
|
9
|
+
self.col_offset = col_offset
|
|
10
|
+
self.complexity = complexity
|
|
11
|
+
self.h1 = 0
|
|
12
|
+
self.h2 = 0
|
|
13
|
+
self.N1 = 0
|
|
14
|
+
self.N2 = 0
|
|
15
|
+
self.vocabulary = 0
|
|
16
|
+
self.length = 0
|
|
17
|
+
self.calculated_length = 0
|
|
18
|
+
self.volume = 0
|
|
19
|
+
self.difficulty = 0
|
|
20
|
+
self.effort = 0
|
|
21
|
+
self.time = 0
|
|
22
|
+
self.bugs = 0
|
|
23
|
+
self.maintainability_index = 0
|
|
24
|
+
|
|
25
|
+
def to_dict(self) -> dict:
|
|
26
|
+
"""Convert FunctionNode to a dictionary for JSON serialization."""
|
|
27
|
+
return {
|
|
28
|
+
"full_name": self.full_name,
|
|
29
|
+
"name": self.name,
|
|
30
|
+
"lineno": self.lineno,
|
|
31
|
+
"col_offset": self.col_offset,
|
|
32
|
+
"complexity": self.complexity,
|
|
33
|
+
"h1": self.h1,
|
|
34
|
+
"h2": self.h2,
|
|
35
|
+
"N1": self.N1,
|
|
36
|
+
"N2": self.N2,
|
|
37
|
+
"vocabulary": self.vocabulary,
|
|
38
|
+
"length": self.length,
|
|
39
|
+
"calculated_length": self.calculated_length,
|
|
40
|
+
"volume": self.volume,
|
|
41
|
+
"difficulty": self.difficulty,
|
|
42
|
+
"effort": self.effort,
|
|
43
|
+
"time": self.time,
|
|
44
|
+
"bugs": self.bugs,
|
|
45
|
+
"maintainability_index": self.maintainability_index,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
def __dict__(self) -> dict:
|
|
49
|
+
return self.to_dict()
|
src/Tree/ModuleNode.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from Tree.ClassNode import ClassNode
|
|
2
|
+
from Tree.FunctionNode import FunctionNode
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ModuleNode:
|
|
6
|
+
def __init__(
|
|
7
|
+
self,
|
|
8
|
+
full_name: str,
|
|
9
|
+
loc: int,
|
|
10
|
+
lloc: int,
|
|
11
|
+
sloc: int,
|
|
12
|
+
comments: int,
|
|
13
|
+
multi: int,
|
|
14
|
+
blank: int,
|
|
15
|
+
single_comments: int,
|
|
16
|
+
):
|
|
17
|
+
self.full_name = full_name
|
|
18
|
+
self.loc = loc
|
|
19
|
+
self.lloc = lloc
|
|
20
|
+
self.sloc = sloc
|
|
21
|
+
self.comments = comments
|
|
22
|
+
self.multi = multi
|
|
23
|
+
self.blank = blank
|
|
24
|
+
self.single_comments = single_comments
|
|
25
|
+
self.maintainability_index = 0
|
|
26
|
+
self.classes: list[ClassNode] = []
|
|
27
|
+
self.functions: list[FunctionNode] = []
|
|
28
|
+
|
|
29
|
+
def to_dict(self) -> dict:
|
|
30
|
+
return {
|
|
31
|
+
"full_name": self.full_name,
|
|
32
|
+
"loc": self.loc,
|
|
33
|
+
"lloc": self.lloc,
|
|
34
|
+
"sloc": self.sloc,
|
|
35
|
+
"comments": self.comments,
|
|
36
|
+
"multi": self.multi,
|
|
37
|
+
"blank": self.blank,
|
|
38
|
+
"single_comments": self.single_comments,
|
|
39
|
+
"maintainability_index": self.maintainability_index,
|
|
40
|
+
"classes": [c.to_dict() for c in self.classes],
|
|
41
|
+
"functions": [f.to_dict() for f in self.functions],
|
|
42
|
+
}
|
src/__init__.py
ADDED
|
File without changes
|
src/codemetrics.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""main module"""
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
from Application.Application import Application
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main():
|
|
9
|
+
"""cli entry point to application"""
|
|
10
|
+
application = Application()
|
|
11
|
+
application.run(sys.argv)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
if __name__ == "__main__":
|
|
15
|
+
main()
|