Merge "Allow to search mandatory packages in all forest"
This commit is contained in:
commit
1508e35df2
@ -21,12 +21,14 @@ import logging
|
||||
|
||||
import six
|
||||
|
||||
from packetary import objects
|
||||
from packetary import schemas
|
||||
|
||||
from packetary.api.context import Context
|
||||
from packetary.api.options import RepositoryCopyOptions
|
||||
from packetary.controllers import RepositoryController
|
||||
from packetary.library.functions import compose
|
||||
from packetary import objects
|
||||
from packetary import schemas
|
||||
from packetary.objects.package_relation import PackageRelation
|
||||
|
||||
from packetary.api.loaders import get_packages_traverse
|
||||
from packetary.api.loaders import load_package_relations
|
||||
@ -37,6 +39,12 @@ from packetary.api.validators import declare_schema
|
||||
logger = logging.getLogger(__package__)
|
||||
|
||||
|
||||
_MANDATORY = {
|
||||
"exact": "=",
|
||||
"newest": ">=",
|
||||
}
|
||||
|
||||
|
||||
class RepositoryApi(object):
|
||||
"""Provides high-level API to operate with repositories."""
|
||||
|
||||
@ -149,16 +157,24 @@ class RepositoryApi(object):
|
||||
requirements.get('repositories'), package_relations.append
|
||||
)
|
||||
for repo in repositories:
|
||||
tree = forest.add_tree(repo.priority)
|
||||
self.controller.load_packages(
|
||||
repo,
|
||||
compose(
|
||||
forest.add_tree(repo.priority).add,
|
||||
tree.add,
|
||||
packages_traverse
|
||||
)
|
||||
)
|
||||
return forest.get_packages(
|
||||
package_relations, requirements.get('mandatory', True)
|
||||
)
|
||||
mandatory = requirements.get('mandatory')
|
||||
if mandatory:
|
||||
for package in tree.mandatory_packages:
|
||||
package_relations.append(
|
||||
PackageRelation.from_args(
|
||||
(package.name,
|
||||
_MANDATORY[requirements['mandatory']],
|
||||
package.version)))
|
||||
|
||||
return forest.get_packages(package_relations)
|
||||
|
||||
packages = set()
|
||||
self._load_packages(repositories, packages.add)
|
||||
|
@ -44,12 +44,10 @@ class PackagesForest(object):
|
||||
tree = self.trees[priority] = PackagesTree()
|
||||
return tree
|
||||
|
||||
def get_packages(self, requirements, include_mandatory=False):
|
||||
def get_packages(self, requirements):
|
||||
"""Get the packages according requirements.
|
||||
|
||||
:param requirements: the list of requirements
|
||||
:param include_mandatory: if true, the mandatory packages will be
|
||||
included to result
|
||||
:return list of packages to copy
|
||||
"""
|
||||
|
||||
@ -61,12 +59,6 @@ class PackagesForest(object):
|
||||
unresolved = set()
|
||||
stack = [(None, requirements)]
|
||||
|
||||
if include_mandatory:
|
||||
for tree in six.itervalues(self.trees):
|
||||
for mandatory in tree.mandatory_packages:
|
||||
resolved.add(mandatory)
|
||||
stack.append((mandatory, mandatory.requires))
|
||||
|
||||
while stack:
|
||||
pkg, requirements = stack.pop()
|
||||
for required in requirements:
|
||||
|
@ -68,7 +68,7 @@ REQUIREMENTS_SCHEMA = {
|
||||
}
|
||||
},
|
||||
"mandatory": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"enum": ["exact", "newest"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,10 +20,12 @@ from packetary import objects
|
||||
|
||||
|
||||
def gen_repository(name="test", url="file:///test",
|
||||
architecture="x86_64", origin="Test", **kwargs):
|
||||
architecture="x86_64", priority=99,
|
||||
origin="Test", **kwargs):
|
||||
"""Helper to create Repository object with default attributes."""
|
||||
url = kwargs.pop("uri", url)
|
||||
return objects.Repository(name, url, architecture, origin, **kwargs)
|
||||
return objects.Repository(name, url, architecture, priority, origin,
|
||||
**kwargs)
|
||||
|
||||
|
||||
def gen_relation(name="test", version=None, alternative=None):
|
||||
|
@ -96,22 +96,11 @@ class TestPackagesForest(base.TestCase):
|
||||
p22, forest.find(generator.gen_relation("package2", [">=", 2]))
|
||||
)
|
||||
|
||||
def test_get_packages_with_mandatory(self):
|
||||
def test_get_packages(self):
|
||||
forest = PackagesForest()
|
||||
self._generate_packages(forest)
|
||||
packages = forest.get_packages(
|
||||
[generator.gen_relation("package3")], True
|
||||
)
|
||||
self.assertItemsEqual(
|
||||
["package1", "package2", "package3", "package4", "package5"],
|
||||
(x.name for x in packages)
|
||||
)
|
||||
|
||||
def test_get_packages_without_mandatory(self):
|
||||
forest = PackagesForest()
|
||||
self._generate_packages(forest)
|
||||
packages = forest.get_packages(
|
||||
[generator.gen_relation("package3")], False
|
||||
[generator.gen_relation("package3")]
|
||||
)
|
||||
self.assertItemsEqual(
|
||||
["package2", "package3", "package5"],
|
||||
|
@ -79,8 +79,12 @@ class TestRepositoryApi(base.TestCase):
|
||||
name='{0}_5'.format(r.name), repository=r,
|
||||
requires=[generator.gen_relation("unresolved")]
|
||||
),
|
||||
generator.gen_package(
|
||||
name='package10', repository=r, mandatory=True,
|
||||
requires=None, version=counter + 10
|
||||
)
|
||||
]
|
||||
for r in self.repos
|
||||
for counter, r in enumerate(self.repos)
|
||||
]
|
||||
self.controller.load_packages.side_effect = self.packages
|
||||
|
||||
@ -139,7 +143,7 @@ class TestRepositoryApi(base.TestCase):
|
||||
self._generate_repositories(1)
|
||||
self._generate_packages()
|
||||
packages = self.api.get_packages(self.repos_data)
|
||||
self.assertEqual(5, len(self.packages[0]))
|
||||
self.assertEqual(6, len(self.packages[0]))
|
||||
self.assertItemsEqual(self.packages[0], packages)
|
||||
jsonschema_mock.validate.assert_called_once_with(
|
||||
self.repos_data, self.api._get_repositories_data_schema()
|
||||
@ -148,10 +152,30 @@ class TestRepositoryApi(base.TestCase):
|
||||
def test_get_packages_by_requirements(self, jsonschema_mock):
|
||||
self._generate_repositories(2)
|
||||
self._generate_packages()
|
||||
requirements = {
|
||||
'packages': [{"name": "repo0_1"}],
|
||||
'repositories': [{"name": "repo1"}]
|
||||
}
|
||||
packages = self.api.get_packages(self.repos_data, requirements)
|
||||
expected_packages = [self.packages[0][0]] + self.packages[1]
|
||||
self.assertItemsEqual(
|
||||
[x.name for x in expected_packages],
|
||||
[x.name for x in packages]
|
||||
)
|
||||
repos_schema = self.api._get_repositories_data_schema()
|
||||
jsonschema_mock.validate.assert_has_calls([
|
||||
mock.call(self.repos_data, repos_schema),
|
||||
mock.call(requirements, schemas.REQUIREMENTS_SCHEMA)
|
||||
], any_order=True)
|
||||
|
||||
def test_get_packages_by_requirements_newest_mandatory(self,
|
||||
jsonschema_mock):
|
||||
self._generate_repositories(2)
|
||||
self._generate_packages()
|
||||
requirements = {
|
||||
'packages': [{"name": "repo0_1"}],
|
||||
'repositories': [{"name": "repo1"}],
|
||||
'mandatory': True
|
||||
'mandatory': "newest"
|
||||
}
|
||||
packages = self.api.get_packages(self.repos_data, requirements)
|
||||
expected_packages = self.packages[0][:3] + self.packages[1]
|
||||
@ -165,6 +189,29 @@ class TestRepositoryApi(base.TestCase):
|
||||
mock.call(requirements, schemas.REQUIREMENTS_SCHEMA)
|
||||
], any_order=True)
|
||||
|
||||
def test_get_packages_by_requirements_exact_mandatory(self,
|
||||
jsonschema_mock):
|
||||
self._generate_repositories(2)
|
||||
self._generate_packages()
|
||||
requirements = {
|
||||
'packages': [{"name": "repo0_1"}],
|
||||
'repositories': [{"name": "repo1"}],
|
||||
'mandatory': "exact"
|
||||
}
|
||||
packages = self.api.get_packages(self.repos_data, requirements)
|
||||
expected_packages = self.packages[0][:3] + \
|
||||
[self.packages[0][-1]] + \
|
||||
self.packages[1]
|
||||
self.assertItemsEqual(
|
||||
[x.name for x in expected_packages],
|
||||
[x.name for x in packages]
|
||||
)
|
||||
repos_schema = self.api._get_repositories_data_schema()
|
||||
jsonschema_mock.validate.assert_has_calls([
|
||||
mock.call(self.repos_data, repos_schema),
|
||||
mock.call(requirements, schemas.REQUIREMENTS_SCHEMA)
|
||||
], any_order=True)
|
||||
|
||||
def test_clone_repositories_as_is(self, jsonschema_mock):
|
||||
self._generate_repositories(1)
|
||||
self._generate_packages()
|
||||
@ -193,7 +240,6 @@ class TestRepositoryApi(base.TestCase):
|
||||
requirements = {
|
||||
'packages': [{"name": "repo0_1"}],
|
||||
'repositories': [{"name": "repo1"}],
|
||||
'mandatory': False
|
||||
}
|
||||
self.controller.assign_packages.return_value = [0, 1, 1] * 3
|
||||
stats = self.api.clone_repositories(
|
||||
|
Loading…
Reference in New Issue
Block a user