Verified Commit 5c491242 authored by David Runge's avatar David Runge
Browse files

Correct and extend models and defaults

repo_management/defaults.py:
Add the IntEnum `RepoDbType` to be able to identify/address the
different types of binary database files (e.g. .db vs. .files).
Change the %LICENSE% entry in `DESC_JSON` to not track the name in
plural (use "license" instead of "licenses") to stay in line with the
naming of the original variable.
Add `DB_USER`, `DB_GROUP`, `DB_FILE_MODE`, `DB_DIR_MODE`, to provide
defaults for which user and group to create files and directories with
which file mode for, when generating a database file.

repo_management/models.py:
Change the `License` model to track an optional list of license
identifiers using the singular term ("license" instead of "licenses") to
have more predictable and coherent naming of variables and attributes.
Add `Base` to `OutputPackageBase` as this way the model is more complete
and it becomes much easier to use it, without having to also pass the
pkgbase alongside it.
Add the convenience method `get_packages_as_models()` to
`OutputPackageBase` which returns the list of packages as tuples of
`PackageDesc` and `Files`.
Extend `PackageDesc` by the convenience method `get_output_package()` to
easily convert an instance of `PackageDesc` and an optional instance of
`Files` to an instance of `OutputPackage`.
Move the declaration of `OutputPackage` above that of `PackageDesc` so
that `PackageDesc.get_output_package()` can declare typing.

tests/test_models.py
Add tests for `PackageDesc.get_output_package()` and
`OutputPackageBase.get_packages_as_models()`.
parent 002b821e
from enum import IntEnum from enum import IntEnum
from typing import Dict, Union from typing import Dict, Union
DB_USER = "root"
DB_GROUP = "root"
DB_FILE_MODE = "0644"
DB_DIR_MODE = "0755"
class RepoDbMemberType(IntEnum): class RepoDbMemberType(IntEnum):
UNKNOWN = 0 UNKNOWN = 0
...@@ -8,6 +13,21 @@ class RepoDbMemberType(IntEnum): ...@@ -8,6 +13,21 @@ class RepoDbMemberType(IntEnum):
FILES = 2 FILES = 2
class RepoDbType(IntEnum):
"""An IntEnum to distinguish types of binary repository database files
Attributes
----------
DEFAULT: int
Use this to identify .db files
FILES: int
Use this to identify .files files
"""
DEFAULT = 0
FILES = 2
class FieldType(IntEnum): class FieldType(IntEnum):
STRING = 0 STRING = 0
INT = 1 INT = 1
...@@ -30,7 +50,7 @@ DESC_JSON: Dict[str, Dict[str, Union[str, FieldType]]] = { ...@@ -30,7 +50,7 @@ DESC_JSON: Dict[str, Dict[str, Union[str, FieldType]]] = {
"%SHA256SUM%": {"name": "sha256sum", "type": FieldType.STRING}, "%SHA256SUM%": {"name": "sha256sum", "type": FieldType.STRING},
"%PGPSIG%": {"name": "pgpsig", "type": FieldType.STRING}, "%PGPSIG%": {"name": "pgpsig", "type": FieldType.STRING},
"%URL%": {"name": "url", "type": FieldType.STRING}, "%URL%": {"name": "url", "type": FieldType.STRING},
"%LICENSE%": {"name": "licenses", "type": FieldType.STRING_LIST}, "%LICENSE%": {"name": "license", "type": FieldType.STRING_LIST},
"%ARCH%": {"name": "arch", "type": FieldType.STRING}, "%ARCH%": {"name": "arch", "type": FieldType.STRING},
"%BUILDDATE%": {"name": "builddate", "type": FieldType.INT}, "%BUILDDATE%": {"name": "builddate", "type": FieldType.INT},
"%PACKAGER%": {"name": "packager", "type": FieldType.STRING}, "%PACKAGER%": {"name": "packager", "type": FieldType.STRING},
......
import io import io
from typing import List, Optional from typing import List, Optional, Tuple
from pydantic import BaseModel from pydantic import BaseModel
...@@ -108,7 +108,7 @@ class License(BaseModel): ...@@ -108,7 +108,7 @@ class License(BaseModel):
"""A model describing the %LICENSE% header in a 'desc' file, which type it represents and whether it is required or """A model describing the %LICENSE% header in a 'desc' file, which type it represents and whether it is required or
not""" not"""
licenses: List[str] license: Optional[List[str]]
class Arch(BaseModel): class Arch(BaseModel):
...@@ -185,10 +185,9 @@ class PackageFiles(Name, Files): ...@@ -185,10 +185,9 @@ class PackageFiles(Name, Files):
pass pass
class PackageDesc( class OutputPackage(
Arch, Arch,
Backup, Backup,
Base,
BuildDate, BuildDate,
Conflicts, Conflicts,
CSize, CSize,
...@@ -196,46 +195,30 @@ class PackageDesc( ...@@ -196,46 +195,30 @@ class PackageDesc(
Desc, Desc,
CheckDepends, CheckDepends,
FileName, FileName,
Files,
Groups, Groups,
ISize, ISize,
License, License,
MakeDepends,
Md5Sum, Md5Sum,
Name, Name,
OptDepends, OptDepends,
Packager,
PgpSig, PgpSig,
Provides, Provides,
Replaces, Replaces,
Sha256Sum, Sha256Sum,
Url, Url,
Version,
): ):
"""A model describing all headers in a 'desc' file, which type they represent and whether they are required or """A model describing all required attributes for a package in the context of an output file, that describes a
not""" (potential) list of packages based upon its pkgbase
pass
class RepoDbMemberType(BaseModel):
"""A model describing an attribute used to identify/ distinguish different types of repo database file types (e.g.
'desc' and 'files' files, which are contained in a repository database file).
The file types are distinguished with the help of the IntEnum defaults.REpoDbFileType
""" """
member_type: defaults.RepoDbMemberType pass
class RepoDbMemberData(Name, RepoDbMemberType):
data: io.StringIO
class Config:
arbitrary_types_allowed = True
class OutputPackage( class PackageDesc(
Arch, Arch,
Backup, Backup,
Base,
BuildDate, BuildDate,
Conflicts, Conflicts,
CSize, CSize,
...@@ -243,27 +226,68 @@ class OutputPackage( ...@@ -243,27 +226,68 @@ class OutputPackage(
Desc, Desc,
CheckDepends, CheckDepends,
FileName, FileName,
Files,
Groups, Groups,
ISize, ISize,
License, License,
MakeDepends,
Md5Sum, Md5Sum,
Name, Name,
OptDepends, OptDepends,
Packager,
PgpSig, PgpSig,
Provides, Provides,
Replaces, Replaces,
Sha256Sum, Sha256Sum,
Url, Url,
Version,
): ):
"""A model describing all required attributes for a package in the context of an output file, that describes a """A model describing all headers in a 'desc' file, which type they represent and whether they are required or
(potential) list of packages based upon its pkgbase not"""
def get_output_package(self, files: Optional[Files]) -> OutputPackage:
"""Transform the PackageDesc model and an optional Files model into an OutputPackage model
Parameters
----------
files: Optional[Files]:
A pydantic model, that represents the list of files, that belong to the package described by self
Returns
-------
OutputPackage
A pydantic model, that describes a package and its list of files
"""
desc_dict = self.dict()
# remove attributes, that are represented on the pkgbase level
for name in ["base", "makedepends", "packager", "version"]:
if desc_dict.get(name):
del desc_dict[name]
if files:
return OutputPackage(**desc_dict, **files.dict())
else:
return OutputPackage(**desc_dict)
class RepoDbMemberType(BaseModel):
"""A model describing an attribute used to identify/ distinguish different types of repo database file types (e.g.
'desc' and 'files' files, which are contained in a repository database file).
The file types are distinguished with the help of the IntEnum defaults.REpoDbFileType
""" """
pass member_type: defaults.RepoDbMemberType
class RepoDbMemberData(Name, RepoDbMemberType):
data: io.StringIO
class Config:
arbitrary_types_allowed = True
class OutputPackageBase( class OutputPackageBase(
Base,
MakeDepends, MakeDepends,
Packager, Packager,
Version, Version,
...@@ -273,3 +297,45 @@ class OutputPackageBase( ...@@ -273,3 +297,45 @@ class OutputPackageBase(
""" """
packages: List[OutputPackage] packages: List[OutputPackage]
def get_packages_as_models(self) -> List[Tuple[PackageDesc, Files]]:
"""Return the list of packages as tuples of PackageDesc and Files models
Returns
-------
List[Tuple[PackageDesc, Files]]
A list of tuples with one PackageDesc and one Files each
"""
return [
(
PackageDesc(
arch=package.arch,
backup=package.backup,
base=self.base,
builddate=package.builddate,
checkdepends=package.checkdepends,
conflicts=package.conflicts,
csize=package.csize,
depends=package.depends,
desc=package.desc,
filename=package.filename,
groups=package.groups,
isize=package.isize,
license=package.license,
makedepends=self.makedepends,
md5sum=package.md5sum,
name=package.name,
optdepends=package.optdepends,
packager=self.packager,
pgpsig=package.pgpsig,
provides=package.provides,
replaces=package.replaces,
sha256sum=package.sha256sum,
url=package.url,
version=self.version,
),
Files(files=package.files),
)
for package in self.packages
]
from typing import List, Optional, Tuple
from pytest import mark
from repo_management import models
@mark.parametrize(
"output_package, package_desc, files",
[
(
models.OutputPackage(
arch="foo",
builddate=1,
csize=1,
desc="foo",
filename="foo",
files=["foo", "bar"],
isize=1,
license=["foo"],
md5sum="foo",
name="foo",
pgpsig="foo",
sha256sum="foo",
url="foo",
),
models.PackageDesc(
arch="foo",
base="foo",
builddate=1,
csize=1,
desc="foo",
filename="foo",
isize=1,
license=["foo"],
md5sum="foo",
name="foo",
packager="foo",
pgpsig="foo",
sha256sum="foo",
url="foo",
version="foo",
),
models.Files(files=["foo", "bar"]),
),
(
models.OutputPackage(
arch="foo",
builddate=1,
csize=1,
desc="foo",
filename="foo",
isize=1,
license=["foo"],
md5sum="foo",
name="foo",
pgpsig="foo",
sha256sum="foo",
url="foo",
),
models.PackageDesc(
arch="foo",
base="foo",
builddate=1,
csize=1,
desc="foo",
filename="foo",
isize=1,
license=["foo"],
md5sum="foo",
name="foo",
packager="foo",
pgpsig="foo",
sha256sum="foo",
url="foo",
version="foo",
),
None,
),
],
)
def test_package_desc_get_output_package(
output_package: models.OutputPackage,
package_desc: models.PackageDesc,
files: Optional[models.Files],
) -> None:
assert output_package == package_desc.get_output_package(files)
@mark.parametrize(
"models_list, output_package_base",
[
(
[
(
models.PackageDesc(
arch="foo",
base="foo",
builddate=1,
csize=1,
desc="foo",
filename="foo",
isize=1,
license=["foo"],
md5sum="foo",
name="foo",
packager="foo",
pgpsig="foo",
sha256sum="foo",
url="foo",
version="foo",
),
models.Files(files=["foo", "bar"]),
),
],
models.OutputPackageBase(
base="foo",
packager="foo",
version="foo",
packages=[
models.OutputPackage(
arch="foo",
builddate=1,
csize=1,
desc="foo",
filename="foo",
files=["foo", "bar"],
isize=1,
license=["foo"],
md5sum="foo",
name="foo",
pgpsig="foo",
sha256sum="foo",
url="foo",
),
],
),
),
],
)
def test_output_package_base_get_packages_as_models(
models_list: List[Tuple[models.PackageDesc, models.Files]],
output_package_base: models.OutputPackageBase,
) -> None:
assert models_list == output_package_base.get_packages_as_models()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment