Improve handling of dates in config

This commit is contained in:
Avram Lubkin 2023-07-05 18:43:06 -04:00 коммит произвёл Avram Lubkin
Родитель 35dee95e4d
Коммит 61a4efeb38
4 изменённых файлов: 32 добавлений и 18 удалений

Просмотреть файл

@ -159,21 +159,18 @@ def main(args: Optional[Sequence[str]] = None):
datefmt="%m-%d %H:%M:%S",
)
# Start with a basic configuration object
config: BaseConfig = BaseConfig()
# If a full configuration is required, CLI parser would ensure this is set
if options.config:
options_values = {field: getattr(options, field, None) for field in BaseConfig.__fields__}
try:
config = Config(**YAML.load(options.config))
config = Config(**YAML.load(options.config) | options_values)
except (ValidationError, YAMLError) as e:
print(f"Unable to validate config file: {options.config}")
sys.exit(e)
# Overwrite some values if they were specified on the command line
for option in ("downstream_since", "upstream_since"):
if hasattr(options, option):
setattr(config, option, getattr(options, option))
# Fallback to basic configuration
else:
config: BaseConfig = BaseConfig(**vars(options))
# Get database object
database = DatabaseDriver(dry_run=options.dry_run, echo=options.verbose > 2)

Просмотреть файл

@ -6,9 +6,10 @@ Configuration data model
from typing import Dict, Optional, Tuple
import approxidate
from pydantic import AnyUrl, BaseModel, validator
from comma.util import DateString
class Target(BaseModel):
"""
@ -35,16 +36,19 @@ class BaseConfig(BaseModel):
Minimal configuration model
"""
downstream_since: Optional[str] = None
upstream_since: Optional[str] = None
downstream_since: Optional[DateString] = None
upstream_since: Optional[DateString] = None
@validator("downstream_since", "upstream_since")
def check_date(cls, value: str):
"""Ensure date can be interpreted"""
def coerce_date(cls, value: str):
"""Coerce date string"""
approxidate.approx(value)
return value if value is None else DateString(value)
return value
class Config:
"""Model configuration"""
validate_assignment = True
class Config(BaseConfig):

Просмотреть файл

@ -4,6 +4,18 @@
Utility functions and classes
"""
import approxidate
class DateString(str):
"""
Wrapper for build-in string type with an additional attribute, epoch
"""
def __init__(self, object_, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self.epoch: float = approxidate.approx(str(object_))
def format_diffs(commit, paths):
"""

Просмотреть файл

@ -9,9 +9,10 @@ import pathlib
import re
from typing import Any, Iterable, List, Optional, Set, Tuple
import approxidate
import git
from comma.util import DateString
LOGGER = logging.getLogger(__name__)
@ -128,7 +129,7 @@ class Repo:
return self._tracked_paths
def fetch_remote_ref(
self, remote: str, local_ref: str, remote_ref: str, since: Optional[str] = None
self, remote: str, local_ref: str, remote_ref: str, since: Optional[DateString] = None
) -> None:
"""
Shallow fetch remote reference so it is available locally
@ -178,7 +179,7 @@ class Repo:
# If last commit for revision is in the fetch window, expand depth
# This check is necessary because some servers will throw an error when there are
# no commits in the fetch window
if commit_date >= approxidate.approx(since):
if commit_date >= since.epoch:
LOGGER.info(
'Fetching ref %s from remote %s shallow since "%s"',
remote_ref,