Skip to content

Commit c11d542

Browse files
committed
feat(config): Config object
1 parent 02f5af8 commit c11d542

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

src/vcspull/config.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@
55
A lot of these items are todo.
66
77
"""
8+
import dataclasses
89
import fnmatch
910
import logging
1011
import os
1112
import pathlib
1213
import typing as t
1314

15+
import yaml
16+
17+
from libvcs._internal.shortcuts import create_project
1418
from libvcs._internal.types import StrPath
1519
from libvcs.sync.git import GitRemote
1620
from vcspull._internal.config_reader import ConfigReader
@@ -24,6 +28,83 @@
2428
if t.TYPE_CHECKING:
2529
from typing_extensions import TypeGuard
2630

31+
from libvcs.sync.git import GitSync
32+
from libvcs.sync.hg import HgSync
33+
from libvcs.sync.svn import SvnSync
34+
35+
Repo = t.Union["GitSync", "HgSync", "SvnSync"]
36+
37+
38+
@dataclasses.dataclass
39+
class Config:
40+
repo_dict_map: list["Repo"]
41+
repos: list["Repo"] = dataclasses.field(init=False, default_factory=list)
42+
43+
def __post_init__(self):
44+
for repo in self.repo_dict_map:
45+
if isinstance(repo, dict):
46+
self.repos.append(create_project(**repo)) # type:ignore
47+
48+
def filter_repos(self, **kwargs) -> list["Repo"]:
49+
return [] # filter code
50+
51+
@classmethod
52+
def from_yaml_file(cls, file_path: pathlib.Path, cwd=pathlib.Path.cwd()):
53+
# load yaml
54+
raw_config = yaml.load(open(file_path).read(), Loader=yaml.Loader)
55+
repos: list[ConfigDict] = []
56+
for directory, repo_map in raw_config.items():
57+
assert isinstance(repo_map, dict)
58+
for repo, repo_data in repo_map.items():
59+
conf: dict = {}
60+
61+
if isinstance(repo_data, str):
62+
conf["url"] = repo_data
63+
else:
64+
conf = update_dict(conf, repo_data)
65+
66+
if "repo" in conf:
67+
if "url" not in conf:
68+
conf["url"] = conf.pop("repo")
69+
else:
70+
conf.pop("repo", None)
71+
72+
if "name" not in conf:
73+
conf["name"] = repo
74+
75+
if "dir" not in conf:
76+
conf["dir"] = expand_dir(
77+
pathlib.Path(expand_dir(pathlib.Path(directory), cwd=cwd))
78+
/ conf["name"],
79+
cwd,
80+
)
81+
82+
if "remotes" in conf:
83+
assert isinstance(conf["remotes"], dict)
84+
for remote_name, url in conf["remotes"].items():
85+
if isinstance(url, GitRemote):
86+
continue
87+
if isinstance(url, str):
88+
conf["remotes"][remote_name] = GitRemote(
89+
name=remote_name, fetch_url=url, push_url=url
90+
)
91+
elif isinstance(url, dict):
92+
assert "push_url" in url
93+
assert "fetch_url" in url
94+
conf["remotes"][remote_name] = GitRemote(
95+
name=remote_name, **url
96+
)
97+
98+
def is_valid_config_dict(val: t.Any) -> "TypeGuard[ConfigDict]":
99+
assert isinstance(val, dict)
100+
return True
101+
102+
assert is_valid_config_dict(conf)
103+
repos.append(conf)
104+
105+
# assert validate_config(config) # mypy happy
106+
return cls(repo_dict_map=repos) # type:ignore
107+
27108

28109
def expand_dir(
29110
_dir: pathlib.Path, cwd: pathlib.Path = pathlib.Path.cwd()

0 commit comments

Comments
 (0)