diff --git a/.travis/script.sh b/.travis/script.sh index 2779535550..d168832f04 100755 --- a/.travis/script.sh +++ b/.travis/script.sh @@ -83,6 +83,9 @@ export CMD_STDIN_PREFIX="sudo kubectl exec -i $PULP_API_POD --" # The alias does not seem to work in Travis / the scripting framework #alias pytest="$CMD_PREFIX pytest" +cat test_requirements.txt | $CMD_STDIN_PREFIX bash -c "cat > /tmp/test_requirements.txt" +$CMD_PREFIX pip3 install -r /tmp/test_requirements.txt + # Run unit tests. $CMD_PREFIX bash -c "PULP_DATABASES__default__USER=postgres django-admin test --noinput /usr/local/lib/python${TRAVIS_PYTHON_VERSION}/site-packages/pulpcore/tests/unit/" diff --git a/CHANGES/5612.misc b/CHANGES/5612.misc new file mode 100644 index 0000000000..a047b94730 --- /dev/null +++ b/CHANGES/5612.misc @@ -0,0 +1 @@ +Fix plugin API documentation post-merge diff --git a/docs/contributing/index.rst b/docs/contributing/index.rst index 6e7cd09c99..4d342fd103 100644 --- a/docs/contributing/index.rst +++ b/docs/contributing/index.rst @@ -32,7 +32,7 @@ Plugin Development ------------------ Developers interested in writing plugins should reference the `Pulp Plugin API -<../../../pulpcore-plugin/nightly/>`_ documentation. +<../plugins/nightly/>`_ documentation. Reference diff --git a/docs/index.rst b/docs/index.rst index 3a2a31e55d..483af7123b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -5,7 +5,7 @@ This documentation is for `pulpcore`, which is used with plugins to fetch, uploa arbitrary content types. Anyone interested in writing a plugin should reference the `Pulp Plugin API -<../../pulpcore-plugin/nightly/>`_ documentation. +`_ documentation. How to Navigate the pulpcore and plugin docs diff --git a/docs/installation/instructions.rst b/docs/installation/instructions.rst index 629767cdb7..a762a47017 100644 --- a/docs/installation/instructions.rst +++ b/docs/installation/instructions.rst @@ -53,7 +53,7 @@ PyPI Installation 4. Install Pulp using pip:: - $ pip install pulpcore-plugin pulpcore + $ pip install pulpcore .. note:: @@ -61,8 +61,6 @@ PyPI Installation $ git clone https://github.com/pulp/pulpcore.git $ pip install -e ./pulpcore[postgres] - $ git clone https://github.com/pulp/pulpcore-plugin.git - $ pip install -e ./pulpcore-plugin 5. Follow the :ref:`configuration instructions ` to set the ``SECRET_KEY``. diff --git a/docs/plugins/CHANGES.rst b/docs/plugins/CHANGES.rst deleted file mode 100644 index cb28b38e5f..0000000000 --- a/docs/plugins/CHANGES.rst +++ /dev/null @@ -1,139 +0,0 @@ -========= -Changelog -========= - -.. - You should *NOT* be adding new change log entries to this file, this - file is managed by towncrier. You *may* edit previous change logs to - fix problems like typo corrections or such. - To add a new change log entry, please see - https://docs.pulpproject.org/en/3.0/nightly/contributing/git.html#changelog-update - - WARNING: Don't drop the next directive! - -.. towncrier release notes start - -0.1.0rc7 (2019-10-15) -===================== - - -Features --------- - -- Add new `repo_key` class attribute to `Content` which defaults to an empty tuple. Subclasses should - use `repo_key` to specify the names of fields, which together should be unique per Repository. - Anytime `RepositoryVersion.add_content()` is called, it now automatically removes content that - matches the `repo_key`. - `#5008 `_ -- Add a ReadOnlyContentViewSet for plugin writers. - `#5535 `_ - - -Bugfixes --------- - -- Fix `fields` filter for `SingleArtifactContentUploadSerializer` - `#5543 `_ - - -Improved Documentation ----------------------- - -- Document explicit definition of ref_name on the serializer. - `#5562 `_ - - -Deprecations and Removals -------------------------- - -- Remove pulpcore.plugin.tasking.Task and expose pulpcore.models.Task instead. - `#5442 `_ -- Change `_id`, `_created`, `_last_updated`, `_href` to `pulp_id`, `pulp_created`, `pulp_last_updated`, `pulp_href` - `#5457 `_ -- Removing `non_fatal_errors` from `Task`. - `#5537 `_ - - ----- - - -0.1.0rc6.dev (2019-09-30) -========================= - - -Features --------- - -- Setting `code` on `ProgressBar`. - `#5184 `_ -- PublishedMetadata.create_from_file() interface added for creating PublishedMetadata. - `#5304 `_ -- Add SingleArtifactContentUploadSerializer a base class for content serializers that accept uploaded files. - `#5403 `_ -- DeclarativeArtifacts can have an Artifact without a RemoteArtifact. - `#5413 `_ -- Added `plugin_managed` field on repository that plugins can set for repositories that should be managed by plugins and not by users. - `#5421 `_ - - -Improved Documentation ----------------------- - -- Update docs removing database agnostic gotchas. - `#5129 `_ - - -Deprecations and Removals -------------------------- - -- Remove support for mysql/mariadb making postgresql the only supported database. - `#5129 `_ -- PublishedMetadata should no longer be created using the default constructor. - `#5304 `_ -- Replace `ProgressBar` with `ProgressReport` and removing `ProgressSpinner`. - `#5444 `_ -- Remove custom JSONField implementation from public API - `#5465 `_ - - -Misc ----- - -- `#5444 `_ - - ----- - - -0.1.0rc5.dev (2019-09-10) -========================= - - -Features --------- - -- Expose CharInFilter to plugins, which can filter by lists of strings. - `#5182 `_ -- Plugin writers can now define settings programatically. - `#5290 `_ - - -Bugfixes --------- - -- Breaking change on how to subclass Master/Detail models in plugins, now `default_related_name` is required for Detail models. - `#4681 `_ -- Fixes `too many open files` when trying to perform large syncs with many downloads. - `#5323 `_ - - -Improved Documentation ----------------------- - -- Updating docs for subclassing models. - `#4681 `_ -- Added documentation on how to add settings programatically. - `#5290 `_ - - ----- diff --git a/docs/plugins/docs/api-reference/content-app.rst b/docs/plugins/api-reference/content-app.rst similarity index 100% rename from docs/plugins/docs/api-reference/content-app.rst rename to docs/plugins/api-reference/content-app.rst diff --git a/docs/plugins/docs/api-reference/download.rst b/docs/plugins/api-reference/download.rst similarity index 100% rename from docs/plugins/docs/api-reference/download.rst rename to docs/plugins/api-reference/download.rst diff --git a/docs/plugins/docs/api-reference/index.rst b/docs/plugins/api-reference/index.rst similarity index 100% rename from docs/plugins/docs/api-reference/index.rst rename to docs/plugins/api-reference/index.rst diff --git a/docs/plugins/docs/api-reference/models.rst b/docs/plugins/api-reference/models.rst similarity index 100% rename from docs/plugins/docs/api-reference/models.rst rename to docs/plugins/api-reference/models.rst diff --git a/docs/plugins/docs/api-reference/profiling.rst b/docs/plugins/api-reference/profiling.rst similarity index 100% rename from docs/plugins/docs/api-reference/profiling.rst rename to docs/plugins/api-reference/profiling.rst diff --git a/docs/plugins/docs/api-reference/serializers.rst b/docs/plugins/api-reference/serializers.rst similarity index 100% rename from docs/plugins/docs/api-reference/serializers.rst rename to docs/plugins/api-reference/serializers.rst diff --git a/docs/plugins/docs/api-reference/stages.rst b/docs/plugins/api-reference/stages.rst similarity index 100% rename from docs/plugins/docs/api-reference/stages.rst rename to docs/plugins/api-reference/stages.rst diff --git a/docs/plugins/docs/api-reference/storage.rst b/docs/plugins/api-reference/storage.rst similarity index 100% rename from docs/plugins/docs/api-reference/storage.rst rename to docs/plugins/api-reference/storage.rst diff --git a/docs/plugins/docs/api-reference/tasking.rst b/docs/plugins/api-reference/tasking.rst similarity index 100% rename from docs/plugins/docs/api-reference/tasking.rst rename to docs/plugins/api-reference/tasking.rst diff --git a/docs/plugins/docs/api-reference/viewsets.rst b/docs/plugins/api-reference/viewsets.rst similarity index 100% rename from docs/plugins/docs/api-reference/viewsets.rst rename to docs/plugins/api-reference/viewsets.rst diff --git a/docs/plugins/docs/extensions/napoleon_django/__init__.py b/docs/plugins/docs/extensions/napoleon_django/__init__.py deleted file mode 100644 index 8d8c493895..0000000000 --- a/docs/plugins/docs/extensions/napoleon_django/__init__.py +++ /dev/null @@ -1,85 +0,0 @@ -# -*- coding: utf-8 -*- -""" - napoleon-django - ~~~~~~~~~~~~~~~ - - An extension to sphinx.ext.napoleon's Google-style Docstring - with support for custom django blocks "Fields" and "Relations". - - :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -import sphinx -from napoleon_django.docstring import DjangoGoogleDocstring - - -class Config(object): - pass - - -def setup(app): - """Sphinx extension setup function. - - When the extension is loaded, Sphinx imports this module and executes - the ``setup()`` function, which in turn notifies Sphinx of everything - the extension offers. - - Parameters - ---------- - app : sphinx.application.Sphinx - Application object representing the Sphinx process - - See Also - -------- - `The Sphinx documentation on Extensions - `_ - - `The Extension Tutorial `_ - - `The Extension API `_ - - """ - from sphinx.application import Sphinx - if not isinstance(app, Sphinx): - return # probably called by tests - - app.connect('autodoc-process-docstring', _process_docstring) - - return {'version': sphinx.__display_version__, 'parallel_read_safe': True} - - -def _process_docstring(app, what, name, obj, options, lines): - """Process the docstring for a given python object. - - Called when autodoc has read and processed a docstring. `lines` is a list - of docstring lines that `_process_docstring` modifies in place to change - what Sphinx outputs. - - Parameters - ---------- - app : sphinx.application.Sphinx - Application object representing the Sphinx process. - what : str - A string specifying the type of the object to which the docstring - belongs. Valid values: "module", "class", "exception", "function", - "method", "attribute". - name : str - The fully qualified name of the object. - obj : module, class, exception, function, method, or attribute - The object to which the docstring belongs. - options : sphinx.ext.autodoc.Options - The options given to the directive: an object with attributes - inherited_members, undoc_members, show_inheritance and noindex that - are True if the flag option of same name was given to the auto - directive. - lines : list of str - The lines of the docstring, see above. - - .. note:: `lines` is modified *in place* - - """ - result_lines = lines - docstring = DjangoGoogleDocstring(result_lines, app.config, app, what, name, obj, options) - result_lines = docstring.lines() - lines[:] = result_lines[:] diff --git a/docs/plugins/docs/extensions/napoleon_django/docstring.py b/docs/plugins/docs/extensions/napoleon_django/docstring.py deleted file mode 100644 index 85da9628ba..0000000000 --- a/docs/plugins/docs/extensions/napoleon_django/docstring.py +++ /dev/null @@ -1,116 +0,0 @@ -# -*- coding: utf-8 -*- -""" - sphinx.ext.napoleon.docstring - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - - Classes for docstring parsing and formatting. - - - :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. - :license: BSD, see LICENSE for details. -""" - -from sphinx.domains.python import PyObject, PyTypedField -from sphinx.ext.napoleon.docstring import GoogleDocstring - -# Extend the python sphinx domain with support for :field: and :relation: directives, -# as well as their related type directives. These then get used by DjangoGoogleDocstring. -# Using the 'data' role for the :field: and :relation: directives prevents sphinx from trying -# cross-reference them. This role is intended to be used at the module level, but renders -# correctly when used in Model definitions and prevents warnings from sphinx about duplicate -# cross-reference targets on something that shouldn't be cross-referenced. -PyObject.doc_field_types.extend([ - PyTypedField('field', label=('Fields'), rolename='data', - names=('field',), typerolename='obj', typenames=('fieldtype',), - can_collapse=True), - PyTypedField('relation', label=('Relations'), rolename='data', - names=('relation',), typerolename='obj', typenames=('reltype',), - can_collapse=True), -]) - -# Similar to the extensions above, but this rewrites the 'variable' type used for class attrs to -# use the data rolename, which prevents sphinx from attempting to cross-reference class attrs. -for field in PyObject.doc_field_types: - if field.name == 'variable': - field.rolename = 'data' - - -class DjangoGoogleDocstring(GoogleDocstring): - """Add support for Django-specific sections to napoleon's GoogleDocstring parser. - - Parameters - ---------- - docstring : str or List[str] - The docstring to parse, given either as a string or split into - individual lines. - config : Optional[sphinx.ext.napoleon.Config or sphinx.config.Config] - The configuration settings to use. If not given, defaults to the - config object on `app`; or if `app` is not given defaults to the - a new `sphinx.ext.napoleon.Config` object. - - See Also - -------- - :class:`sphinx.ext.napoleon.Config` - - Other Parameters - ---------------- - app : Optional[sphinx.application.Sphinx] - Application object representing the Sphinx process. - what : Optional[str] - A string specifying the type of the object to which the docstring - belongs. Valid values: "module", "class", "exception", "function", - "method", "attribute". - name : Optional[str] - The fully qualified name of the object. - obj : module, class, exception, function, method, or attribute - The object to which the docstring belongs. - options : Optional[sphinx.ext.autodoc.Options] - The options given to the directive: an object with attributes - inherited_members, undoc_members, show_inheritance and noindex that - are True if the flag option of same name was given to the auto - directive. - - """ - def __init__(self, docstring, config=None, app=None, what='', name='', - obj=None, options=None): - # super's __init__ calls _parse, so we need to wrap it to make sure the custom - # django-ness is added to the class before _parse runs. Thus, self._initialized. - # See _parse below for how this attr gets used to delay parsing. - self._initialized = False - super().__init__(docstring, config, app, what, name, obj, options) - self._sections.update({ - 'fields': self._parse_fields_section, - 'relations': self._parse_relations_section, - }) - self._initialized = True - self._parse() - - def _parse(self): - if self._initialized: - return super()._parse() - - def _parse_fields_section(self, section): - return self._parse_django_section(section, 'field') - - def _parse_relations_section(self, section): - return self._parse_django_section(section, 'relation') - - def _parse_django_section(self, section, directive): - # a "django" directive is either field or relation. Use the correct type definition - # based on the value of 'directive' to generate a correctly cross-referenced type link. - # directive and typedirective need to match the name and typename of the custom - # PyTypedFields added to the python sphinx domain above. - if directive == 'field': - typedirective = 'fieldtype' - else: - typedirective = 'reltype' - - lines = [] - for _name, _type, _desc in self._consume_fields(): - field = ':%s %s: ' % (directive, _name) - lines.extend(self._format_block(field, _desc)) - if _type: - lines.append(':%s %s: %s' % (typedirective, _name, _type)) - lines.append('') - return lines diff --git a/docs/plugins/docs/static/.gitignore b/docs/plugins/docs/static/.gitignore deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/docs/plugins/index.rst b/docs/plugins/index.rst index 55be70bb05..7b9aac1d6c 100644 --- a/docs/plugins/index.rst +++ b/docs/plugins/index.rst @@ -6,11 +6,32 @@ Plugins add support for a type of content to Pulp. For example, the For a list of plugins check out our `list of plugins for Pulp 3 `_. -Developers interested in writing plugins should reference the `Pulp Plugin API -<../../../pulpcore-plugin/nightly/>`_ documentation. - And don't hesitate to :ref:`contact us` with any questions during development. Let us know when the plugin is ready and we will be happy to add it to the list of available plugins for Pulp! .. note:: Are we missing a plugin? Let us know via the pulp-dev@redhat.com mailing list. + +Plugin API +========== + +The Pulp Plugin API is versioned separately from Pulp Core. It is governed by `semantic +versioning `_. Backwards incompatible changes may be made until the +Plugin API reaches stability with v1.0. + +Plugin Writer's Guide +--------------------- +.. toctree:: + plugin-writer/index + +Plugin Writer's Reference +------------------------- +.. toctree:: + :maxdepth: 1 + + reference/index + +Plugin API Reference +-------------------- +.. toctree:: + api-reference/index diff --git a/docs/plugins/docs/plugin-writer/concepts/index.rst b/docs/plugins/plugin-writer/concepts/index.rst similarity index 100% rename from docs/plugins/docs/plugin-writer/concepts/index.rst rename to docs/plugins/plugin-writer/concepts/index.rst diff --git a/docs/plugins/docs/plugin-writer/concepts/subclassing/models.rst b/docs/plugins/plugin-writer/concepts/subclassing/models.rst similarity index 100% rename from docs/plugins/docs/plugin-writer/concepts/subclassing/models.rst rename to docs/plugins/plugin-writer/concepts/subclassing/models.rst diff --git a/docs/plugins/docs/plugin-writer/concepts/subclassing/serializers.rst b/docs/plugins/plugin-writer/concepts/subclassing/serializers.rst similarity index 100% rename from docs/plugins/docs/plugin-writer/concepts/subclassing/serializers.rst rename to docs/plugins/plugin-writer/concepts/subclassing/serializers.rst diff --git a/docs/plugins/docs/plugin-writer/concepts/subclassing/viewsets.rst b/docs/plugins/plugin-writer/concepts/subclassing/viewsets.rst similarity index 100% rename from docs/plugins/docs/plugin-writer/concepts/subclassing/viewsets.rst rename to docs/plugins/plugin-writer/concepts/subclassing/viewsets.rst diff --git a/docs/plugins/docs/plugin-writer/concepts/sync_pipeline/sync_pipeline.rst b/docs/plugins/plugin-writer/concepts/sync_pipeline/sync_pipeline.rst similarity index 100% rename from docs/plugins/docs/plugin-writer/concepts/sync_pipeline/sync_pipeline.rst rename to docs/plugins/plugin-writer/concepts/sync_pipeline/sync_pipeline.rst diff --git a/docs/plugins/docs/plugin-writer/concepts/tasks/add-remove.rst b/docs/plugins/plugin-writer/concepts/tasks/add-remove.rst similarity index 100% rename from docs/plugins/docs/plugin-writer/concepts/tasks/add-remove.rst rename to docs/plugins/plugin-writer/concepts/tasks/add-remove.rst diff --git a/docs/plugins/docs/plugin-writer/concepts/tasks/export.rst b/docs/plugins/plugin-writer/concepts/tasks/export.rst similarity index 100% rename from docs/plugins/docs/plugin-writer/concepts/tasks/export.rst rename to docs/plugins/plugin-writer/concepts/tasks/export.rst diff --git a/docs/plugins/docs/plugin-writer/concepts/tasks/publish.rst b/docs/plugins/plugin-writer/concepts/tasks/publish.rst similarity index 100% rename from docs/plugins/docs/plugin-writer/concepts/tasks/publish.rst rename to docs/plugins/plugin-writer/concepts/tasks/publish.rst diff --git a/docs/plugins/docs/plugin-writer/custom-installation-tasks.rst b/docs/plugins/plugin-writer/custom-installation-tasks.rst similarity index 100% rename from docs/plugins/docs/plugin-writer/custom-installation-tasks.rst rename to docs/plugins/plugin-writer/custom-installation-tasks.rst diff --git a/docs/plugins/docs/plugin-writer/index.rst b/docs/plugins/plugin-writer/index.rst similarity index 100% rename from docs/plugins/docs/plugin-writer/index.rst rename to docs/plugins/plugin-writer/index.rst diff --git a/docs/plugins/docs/plugin-writer/planning-guide.rst b/docs/plugins/plugin-writer/planning-guide.rst similarity index 100% rename from docs/plugins/docs/plugin-writer/planning-guide.rst rename to docs/plugins/plugin-writer/planning-guide.rst diff --git a/docs/plugins/docs/plugin-writer/plugin-walkthrough.rst b/docs/plugins/plugin-writer/plugin-walkthrough.rst similarity index 100% rename from docs/plugins/docs/plugin-writer/plugin-walkthrough.rst rename to docs/plugins/plugin-writer/plugin-walkthrough.rst diff --git a/docs/plugins/docs/reference/content-protection.rst b/docs/plugins/reference/content-protection.rst similarity index 100% rename from docs/plugins/docs/reference/content-protection.rst rename to docs/plugins/reference/content-protection.rst diff --git a/docs/plugins/docs/reference/error-handling.rst b/docs/plugins/reference/error-handling.rst similarity index 100% rename from docs/plugins/docs/reference/error-handling.rst rename to docs/plugins/reference/error-handling.rst diff --git a/docs/plugins/docs/reference/how-plugins-work.rst b/docs/plugins/reference/how-plugins-work.rst similarity index 100% rename from docs/plugins/docs/reference/how-plugins-work.rst rename to docs/plugins/reference/how-plugins-work.rst diff --git a/docs/plugins/docs/reference/how-to-doc-api.rst b/docs/plugins/reference/how-to-doc-api.rst similarity index 100% rename from docs/plugins/docs/reference/how-to-doc-api.rst rename to docs/plugins/reference/how-to-doc-api.rst diff --git a/docs/plugins/docs/reference/index.rst b/docs/plugins/reference/index.rst similarity index 100% rename from docs/plugins/docs/reference/index.rst rename to docs/plugins/reference/index.rst diff --git a/docs/plugins/docs/reference/live-api.rst b/docs/plugins/reference/live-api.rst similarity index 100% rename from docs/plugins/docs/reference/live-api.rst rename to docs/plugins/reference/live-api.rst diff --git a/docs/plugins/docs/reference/object-relationships.rst b/docs/plugins/reference/object-relationships.rst similarity index 100% rename from docs/plugins/docs/reference/object-relationships.rst rename to docs/plugins/reference/object-relationships.rst diff --git a/docs/plugins/docs/reference/on-demand-support.rst b/docs/plugins/reference/on-demand-support.rst similarity index 100% rename from docs/plugins/docs/reference/on-demand-support.rst rename to docs/plugins/reference/on-demand-support.rst diff --git a/docs/plugins/docs/reference/releasing.rst b/docs/plugins/reference/releasing.rst similarity index 100% rename from docs/plugins/docs/reference/releasing.rst rename to docs/plugins/reference/releasing.rst diff --git a/docs/workflows/on-demand-downloading.rst b/docs/workflows/on-demand-downloading.rst index 22433ae6a1..12b20104b7 100644 --- a/docs/workflows/on-demand-downloading.rst +++ b/docs/workflows/on-demand-downloading.rst @@ -47,7 +47,7 @@ you will receive an error. Check that plugin's documentation also. .. note:: - Want to add on-demand support to your plugin? See the `Pulp Plugin API <../../pulpcore-plugin/ + Want to add on-demand support to your plugin? See the `Pulp Plugin API <../plugins/ nightly/>`_ documentation for more details on how to add on-demand support to a plugin. diff --git a/flake8.cfg b/flake8.cfg index d0f4155e82..5c7b453f98 100644 --- a/flake8.cfg +++ b/flake8.cfg @@ -1,5 +1,5 @@ [flake8] -exclude = ./docs/*, */migrations/* +exclude = ./docs/*, */migrations/*, ./pulpcore/plugin/docs/* # E401: multiple imports on one line extend-ignore = E401 max-line-length = 100 diff --git a/pulpcore/app/models/publication.py b/pulpcore/app/models/publication.py index 3e91cbc120..8fcb1d3b71 100644 --- a/pulpcore/app/models/publication.py +++ b/pulpcore/app/models/publication.py @@ -180,12 +180,14 @@ def create_from_file(cls, file, publication, relative_path=None): Args: file (django.core.files.File): an open File that contains metadata - publication (Publication): The publication in which the PublishedMetadata is included. + publication (pulpcore.app.models.Publication): The publication in which the + PublishedMetadata is included. relative_path (str): relative path at which the Metadata is published at. If None, the name of the 'file' is used. Returns: - PublishedMetadata: a saved instance of PublishedMetadata + PublishedMetadata (pulpcore.app.models.PublishedMetadata): + A saved instance of PublishedMetadata. """ with transaction.atomic(): diff --git a/pulpcore/plugin/README.rst b/pulpcore/plugin/README.rst index 83b8c04c2b..b4c247a21d 100644 --- a/pulpcore/plugin/README.rst +++ b/pulpcore/plugin/README.rst @@ -1,7 +1,7 @@ **Pulp Plugin API** The Pulp Plugin API is an essential part of the `Pulp Project 3.0+ `__ which provides a set of base -classes that can be implemented in plugins to manage content in a way that is consistent +classes that can be implemented in plugins to manage content in a way that is consistent across plugins, while still allowing plugin writers the freedom to define their workflows as they deem necessary. @@ -11,13 +11,12 @@ The Pulp Plugin API allows plugin writers: - to use tasking system, - and more. -See `Plugin Writer's Guide `__ for more information. +See `Plugin Writer's Guide `__ for more information. Pulp is completely free and open-source! - License: GNUv2 -- Source: https://github.com/pulp/pulpcore-plugin/ For more information, check out the project website: http://www.pulpproject.org