spgit

A static page generator for git repositories

git clone git://git.janzachar.dev/spgit.git


0from pathlib import Path
1import settings
2import git
3import yaml
4
5class Meta:
6    """
7        Holds repo metadata.
8        Things retrieved from .meta.yml
9        as well as in-place generated urls
10    """
11    def __init__(self, path, data):
12        self.name:          str
13        self.description:   str
14        self.info:          dict
15        self.page_url:      str
16        self.clone_url:     str
17
18        self.validate(data)
19
20        self.page_url = f"/{path.name}"
21        self.clone_url = f"git://{settings.HOST}/{path.name}"
22
23    def validate(self, data):
24        self.name = data["name"]
25        self.description = data["description"]
26        self.info = data["info"]
27
28        for x in (self.name, self.description):
29            if not isinstance(x, str):
30                raise TypeError(f"{x} must be str, got {type(self.name).__name__}!")
31
32        if not isinstance(self.info, dict):
33            raise TypeError(f"{self.info} must be dict, got {type(self.name).__name__}!")
34
35
36class Repo:
37    """
38        Repository-related objects in one place.
39        Mainly responsible for validating repos.
40    """
41    def __init__(self, path):
42        self.path:  Path
43        self.repo:  git.Repo
44        self.meta:  Meta
45        self.valid: Bool
46
47        self.path = path
48        try:
49            self.repo = git.Repo(path)
50        except git.exc.InvalidGitRepositoryError as e:
51            print(f"Rejected {self.path}: Invalid repo!")
52            self.valid = False
53            return
54
55        if not self.repo.head.is_valid():
56            print(f"Rejected {self.path}: Invalid HEAD!")
57            self.valid = False
58            return
59
60        try:
61            self.load_yml()
62        except FileNotFoundError, TypeError, KeyError:
63            print(f"Rejected {self.path}: .meta.yml: {e.__name__}: {e}")
64            self.valid = False
65        else:
66            self.valid = True
67
68    def load_yml(self):
69        # Extract '.meta.yml' from HEAD
70        tree = self.repo.head.commit.tree
71        if ".meta.yml" not in tree:
72            raise FileNotFoundError("'.meta.yml' not found in HEAD")
73
74        fp = tree[".meta.yml"].data_stream
75        out = yaml.safe_load(fp)
76
77        self.meta = Meta(self.path, out)
78
79