Обновить git_analyzer.py
This commit is contained in:
@@ -4,37 +4,55 @@ import subprocess
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
class CommitInfo:
|
||||
hash: str
|
||||
short: str
|
||||
author: str
|
||||
date: str
|
||||
timestamp: int
|
||||
message: str
|
||||
def __init__(self, hash, short, author, date, timestamp, message):
|
||||
self.hash = hash
|
||||
self.short = short
|
||||
self.author = author
|
||||
self.date = date
|
||||
self.timestamp = timestamp
|
||||
self.message = message
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
f"CommitInfo(hash={self.hash!r}, short={self.short!r}, author={self.author!r}, "
|
||||
f"date={self.date!r}, timestamp={self.timestamp!r}, message={self.message!r})"
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class BranchInfo:
|
||||
name: str
|
||||
ref: str
|
||||
total_files: int = 0
|
||||
total_lines: int = 0
|
||||
def __init__(self, name, ref, total_files=0, total_lines=0):
|
||||
self.name = name
|
||||
self.ref = ref
|
||||
self.total_files = total_files
|
||||
self.total_lines = total_lines
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
f"BranchInfo(name={self.name!r}, ref={self.ref!r}, "
|
||||
f"total_files={self.total_files!r}, total_lines={self.total_lines!r})"
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class RepositoryInfo:
|
||||
link: str
|
||||
repo_name: str
|
||||
default_branch: str
|
||||
branches: list = field(default_factory=list)
|
||||
commits: list = field(default_factory=list)
|
||||
total_files: int = 0
|
||||
total_lines: int = 0
|
||||
def __init__(self, link, repo_name, default_branch, branches=None, commits=None, total_files=0, total_lines=0):
|
||||
self.link = link
|
||||
self.repo_name = repo_name
|
||||
self.default_branch = default_branch
|
||||
self.branches = branches if branches is not None else []
|
||||
self.commits = commits if commits is not None else []
|
||||
self.total_files = total_files
|
||||
self.total_lines = total_lines
|
||||
|
||||
def __repr__(self):
|
||||
return (
|
||||
f"RepositoryInfo(link={self.link!r}, repo_name={self.repo_name!r}, "
|
||||
f"default_branch={self.default_branch!r}, branches={self.branches!r}, "
|
||||
f"commits={self.commits!r}, total_files={self.total_files!r}, "
|
||||
f"total_lines={self.total_lines!r})"
|
||||
)
|
||||
|
||||
|
||||
LANG_EXTENSIONS = {
|
||||
@@ -317,6 +335,9 @@ def read_file_at_ref(repo_dir, ref, path):
|
||||
|
||||
|
||||
def get_branch_commits(repo_dir, branch_ref):
|
||||
"""Коммиты конкретной ветки от старых к новым, с timestamp.
|
||||
Это нужно, чтобы на старой версии не показывать ветку, которой тогда ещё не было.
|
||||
"""
|
||||
fmt = "%H%x1f%h%x1f%an%x1f%ad%x1f%at%x1f%s"
|
||||
try:
|
||||
out = run_git(["log", branch_ref, "--reverse", "--date=iso", f"--pretty=format:{fmt}"], cwd=repo_dir)
|
||||
@@ -338,6 +359,10 @@ def get_branch_commits(repo_dir, branch_ref):
|
||||
|
||||
|
||||
def branch_first_unique_timestamp(repo_dir, branch_ref, default_ref):
|
||||
"""Когда ветка реально стала отдельной.
|
||||
Git не хранит дату создания ветки, поэтому берём первый коммит ветки,
|
||||
которого нет в основной ветке. Если таких нет — ветка считается старой.
|
||||
"""
|
||||
if branch_ref == default_ref:
|
||||
return None
|
||||
result = run_git_allow_fail(["log", "--reverse", "--format=%at", f"{default_ref}..{branch_ref}"], cwd=repo_dir)
|
||||
@@ -527,6 +552,13 @@ def format_analysis(data):
|
||||
|
||||
|
||||
class GitAnalyzer:
|
||||
"""Главный класс анализа Git-репозиториев.
|
||||
|
||||
В старых версиях проекта логика была набором функций.
|
||||
В OOP-версии интерфейс создаёт объект GitAnalyzer и вызывает его методы.
|
||||
Так проще строить диаграмму классов и объяснять систему как набор объектов.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.languages = LANG_EXTENSIONS
|
||||
self.ignore_dirs = IGNORE_DIRS
|
||||
|
||||
Reference in New Issue
Block a user