diff --git a/docs/user-docs/getting_started.rst b/docs/user-docs/getting_started.rst index 298bb6a9..43165005 100644 --- a/docs/user-docs/getting_started.rst +++ b/docs/user-docs/getting_started.rst @@ -61,6 +61,22 @@ And now we can see that there is one Python package in our repository:: Content Unit Counts: Python Package: 1 +Query Packages in a Repository +------------------------------ + +You can also query the packages in a repository:: + + $ pulp-admin python repo packages --repo-id my_own_pypi --match name=pulp_python_plugins + Name: pulp_python_plugins + Version: 0.0.0 + Author: Pulp Team + Author Email: pulp-list@redhat.com + Description: UNKNOWN + Home Page: http://www.pulpproject.org + License: GPLv2+ + Platform: UNKNOWN + Summary: plugins for python support in pulp + Publish a Python Repository --------------------------- diff --git a/extensions_admin/pulp_python/extensions/admin/packages.py b/extensions_admin/pulp_python/extensions/admin/packages.py new file mode 100644 index 00000000..b31cd1f4 --- /dev/null +++ b/extensions_admin/pulp_python/extensions/admin/packages.py @@ -0,0 +1,50 @@ +""" +Commands related to searching for packages in a Python repository. +""" +from gettext import gettext as _ + +from pulp.client.commands import options +from pulp.client.commands.criteria import DisplayUnitAssociationsCommand + +from pulp_python.common import constants + + +DESC_SEARCH = _('search for packages in a repository') + + +class PackagesCommand(DisplayUnitAssociationsCommand): + """ + This command is used to search for existing Python packages in a repository. + """ + def __init__(self, context): + """ + Initialize the command. + + :param context: The CLI context + :type context: pulp.client.extensions.core.ClientContext + """ + super(PackagesCommand, self).__init__(self.run, name='packages', + description=DESC_SEARCH) + self.context = context + self.prompt = context.prompt + + def run(self, **kwargs): + """ + Query the server for the packages, and render them for the user. + + :param kwargs: The CLI options passed by the user + :type kwargs: dict + """ + # Retrieve the packages + repo_id = kwargs.pop(options.OPTION_REPO_ID.keyword) + kwargs['type_ids'] = [constants.PACKAGE_TYPE_ID] + packages = self.context.server.repo_unit.search(repo_id, **kwargs).response_body + + order = [] + + if not kwargs.get(self.ASSOCIATION_FLAG.keyword): + packages = [m['metadata'] for m in packages] + # Make sure the key info is at the top; the rest can be alpha + order = ['name', 'version', 'author'] + + self.prompt.render_document_list(packages, order=order) diff --git a/extensions_admin/pulp_python/extensions/admin/pulp_cli.py b/extensions_admin/pulp_python/extensions/admin/pulp_cli.py index f0964916..ab8efd34 100644 --- a/extensions_admin/pulp_python/extensions/admin/pulp_cli.py +++ b/extensions_admin/pulp_python/extensions/admin/pulp_cli.py @@ -6,7 +6,7 @@ from pulp_python.common import constants from pulp_python.extensions.admin.cudl import ( CreatePythonRepositoryCommand, UpdatePythonRepositoryCommand, ListPythonRepositoriesCommand) -from pulp_python.extensions.admin import upload +from pulp_python.extensions.admin import packages, upload SECTION_ROOT = 'python' @@ -55,6 +55,7 @@ def _add_repo_section(context, parent_section): _add_sync_section(context, repo_section) repo_section.add_command(upload.UploadPackageCommand(context)) + repo_section.add_command(packages.PackagesCommand(context)) def _add_publish_section(context, parent_section): diff --git a/extensions_admin/test/unit/admin/test_packages.py b/extensions_admin/test/unit/admin/test_packages.py new file mode 100644 index 00000000..59d523dd --- /dev/null +++ b/extensions_admin/test/unit/admin/test_packages.py @@ -0,0 +1,86 @@ +""" +This module contains tests for the pulp_python.extensions.admin.packages module. +""" +import unittest + +from pulp.client.commands import options +import mock + +from pulp_python.common import constants +from pulp_python.extensions.admin import packages + + +class TestPackagesCommand(unittest.TestCase): + """ + This class contains tests for the PackagesCommand class. + """ + @mock.patch('pulp_python.extensions.admin.packages.DisplayUnitAssociationsCommand.__init__') + def test___init__(self, super___init__): + """ + Assert correct behavior from __init__(). + """ + context = mock.MagicMock() + + c = packages.PackagesCommand(context) + + super___init__.assert_called_once_with(c.run, name='packages', + description=packages.DESC_SEARCH) + self.assertEqual(c.context, context) + self.assertEqual(c.prompt, context.prompt) + + def test_run_with_details(self): + """ + Test the run() method with the details flag. + """ + _packages = ['package_1', 'package_2'] + + def search(_repo_id, **_kwargs): + """ + Fakes the server search. + """ + self.assertEqual(_repo_id, 'some_repo') + self.assertEqual( + _kwargs, + {'type_ids': [constants.PACKAGE_TYPE_ID], c.ASSOCIATION_FLAG.keyword: True}) + + response = mock.MagicMock() + response.response_body = _packages + return response + + context = mock.MagicMock() + context.server.repo_unit.search.side_effect = search + c = packages.PackagesCommand(context) + kwargs = {options.OPTION_REPO_ID.keyword: 'some_repo', c.ASSOCIATION_FLAG.keyword: True} + + c.run(**kwargs) + + c.prompt.render_document_list.assert_called_once_with(_packages, order=[]) + + def test_run_without_details(self): + """ + Test the run() method without the details flag. + """ + _packages = [{'metadata': 'package_1'}, {'metadata': 'package_2'}] + + def search(_repo_id, **_kwargs): + """ + Fakes the server search. + """ + self.assertEqual(_repo_id, 'some_repo') + self.assertEqual( + _kwargs, + {'type_ids': [constants.PACKAGE_TYPE_ID]}) + + response = mock.MagicMock() + response.response_body = _packages + return response + + context = mock.MagicMock() + context.server.repo_unit.search.side_effect = search + c = packages.PackagesCommand(context) + kwargs = {options.OPTION_REPO_ID.keyword: 'some_repo'} + + c.run(**kwargs) + + c.prompt.render_document_list.assert_called_once_with(['package_1', 'package_2'], + order=['name', 'version', 'author']) diff --git a/extensions_admin/test/unit/admin/test_pulp_cli.py b/extensions_admin/test/unit/admin/test_pulp_cli.py index 852fff32..9dec19a4 100644 --- a/extensions_admin/test/unit/admin/test_pulp_cli.py +++ b/extensions_admin/test/unit/admin/test_pulp_cli.py @@ -8,7 +8,7 @@ RunPublishRepositoryCommand, RunSyncRepositoryCommand from pulp.client.extensions.core import PulpCli -from pulp_python.extensions.admin import pulp_cli, upload +from pulp_python.extensions.admin import packages, pulp_cli, upload class TestInitialize(unittest.TestCase): @@ -32,6 +32,7 @@ def test_structure(self): self.assertTrue(isinstance(repo_section.commands['update'], UpdateRepositoryCommand)) self.assertTrue(isinstance(repo_section.commands['list'], ListRepositoriesCommand)) self.assertTrue(isinstance(repo_section.commands['upload'], upload.UploadPackageCommand)) + self.assertTrue(isinstance(repo_section.commands['packages'], packages.PackagesCommand)) section = repo_section.subsections['sync'] self.assertTrue(isinstance(section.commands['run'], RunSyncRepositoryCommand))