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 typing import Dict, Union
DB_USER = "root"
DB_GROUP = "root"
DB_FILE_MODE = "0644"
DB_DIR_MODE = "0755"
class RepoDbMemberType(IntEnum):
UNKNOWN = 0
......@@ -8,6 +13,21 @@ class RepoDbMemberType(IntEnum):
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):
STRING = 0
INT = 1
......@@ -30,7 +50,7 @@ DESC_JSON: Dict[str, Dict[str, Union[str, FieldType]]] = {
"%SHA256SUM%": {"name": "sha256sum", "type": FieldType.STRING},
"%PGPSIG%": {"name": "pgpsig", "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},
"%BUILDDATE%": {"name": "builddate", "type": FieldType.INT},
"%PACKAGER%": {"name": "packager", "type": FieldType.STRING},
......
import io
from typing import List, Optional
from typing import List, Optional, Tuple
from pydantic import 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
not"""
licenses: List[str]
license: Optional[List[str]]
class Arch(BaseModel):
......@@ -185,10 +185,9 @@ class PackageFiles(Name, Files):
pass
class PackageDesc(
class OutputPackage(
Arch,
Backup,
Base,
BuildDate,
Conflicts,
CSize,
......@@ -196,46 +195,30 @@ class PackageDesc(
Desc,
CheckDepends,
FileName,
Files,
Groups,
ISize,
License,
MakeDepends,
Md5Sum,
Name,
OptDepends,
Packager,
PgpSig,
Provides,
Replaces,
Sha256Sum,
Url,
Version,
):
"""A model describing all headers in a 'desc' file, which type they represent and whether they are required or
not"""
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
"""A model describing all required attributes for a package in the context of an output file, that describes a
(potential) list of packages based upon its pkgbase
"""
member_type: defaults.RepoDbMemberType
class RepoDbMemberData(Name, RepoDbMemberType):
data: io.StringIO
class Config:
arbitrary_types_allowed = True
pass
class OutputPackage(
class PackageDesc(
Arch,
Backup,
Base,
BuildDate,
Conflicts,
CSize,
......@@ -243,27 +226,68 @@ class OutputPackage(
Desc,
CheckDepends,
FileName,
Files,
Groups,
ISize,
License,
MakeDepends,
Md5Sum,
Name,
OptDepends,
Packager,
PgpSig,
Provides,
Replaces,
Sha256Sum,
Url,
Version,
):
"""A model describing all required attributes for a package in the context of an output file, that describes a
(potential) list of packages based upon its pkgbase
"""A model describing all headers in a 'desc' file, which type they represent and whether they are required or
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(
Base,
MakeDepends,
Packager,
Version,
......@@ -273,3 +297,45 @@ class OutputPackageBase(
"""
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