Skip to content

Commit 96c8bf8

Browse files
committed
feat(config): Config object
1 parent 9ff3099 commit 96c8bf8

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

src/vcspull/config.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
A lot of these items are todo.
66
77
"""
8+
import dataclasses
89
import fnmatch
910
import logging
1011
import os
@@ -13,7 +14,9 @@
1314
from typing import Literal, Optional, Union
1415

1516
import kaptan
17+
import yaml
1618

19+
from libvcs._internal.shortcuts import create_project
1720
from libvcs._internal.types import StrPath
1821
from libvcs.sync.git import GitRemote
1922

@@ -26,6 +29,83 @@
2629
if t.TYPE_CHECKING:
2730
from typing_extensions import TypeGuard
2831

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

30110
def expand_dir(
31111
_dir: pathlib.Path, cwd: pathlib.Path = pathlib.Path.cwd()

0 commit comments

Comments
 (0)