Skip to content

Commit

Permalink
docs
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com>
  • Loading branch information
jkowalleck committed Sep 19, 2023
1 parent af01f22 commit 82d7cbf
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 112 deletions.
2 changes: 2 additions & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ src_paths =
cyclonedx
tests
typings
examples
tools
2 changes: 0 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ But please read the
[CycloneDX contributing guidelines](https://github.com/CycloneDX/.github/blob/master/CONTRIBUTING.md)
first.

See also: [contrib docs](docs/contributing.rst)

## Setup

This project uses [poetry]. Have it installed and setup first.
Expand Down
5 changes: 5 additions & 0 deletions cyclonedx/exception/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,8 @@ class CycloneDxException(Exception):
Root exception thrown by this library.
"""
pass


class MissingOptionalDependencyException(CycloneDxException):
"""Validation did not happen, due to missing dependencies."""
pass
32 changes: 21 additions & 11 deletions cyclonedx/validation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,20 @@
# SPDX-License-Identifier: Apache-2.0

from abc import ABC, abstractmethod
from typing import TYPE_CHECKING, Any, Optional
from typing import TYPE_CHECKING, Any, Optional, Protocol

if TYPE_CHECKING:
from ..schema import SchemaVersion


class MissingOptionalDependencyException(BaseException):
pass
class ValidationError:
"""Validation failed with this specific error.
Use :attr:`~data` to access the content.
"""

data: Any

class ValidationError:
def __init__(self, data: Any) -> None:
self.data = data

Expand All @@ -36,22 +39,29 @@ def __str__(self) -> str:
return str(self.data)


class _BaseValidator(ABC):
class Validator(Protocol):
"""Validator protocol"""

def validate_str(self, data: str) -> Optional[ValidationError]:
"""Validate a string"""
...


class _BaseValidator(Validator, ABC):
"""this class is non-public. changes without notice may happen."""

def __init__(self, schema_version: 'SchemaVersion') -> None:
self.__schema_version = schema_version
if not self._schema_file:
raise ValueError(f'unsupported schema: {schema_version}')

@property
@abstractmethod
def _schema_file(self) -> Optional[str]:
...

@property
def schema_version(self) -> 'SchemaVersion':
"""get the schema version."""
return self.__schema_version

@property
@abstractmethod
def validate_str(self, data: str) -> Optional[ValidationError]:
def _schema_file(self) -> Optional[str]:
"""get the schema file according to schema version."""
...
26 changes: 22 additions & 4 deletions cyclonedx/validation/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@
from json import loads as json_loads
from typing import TYPE_CHECKING, Any, Optional, Tuple

if TYPE_CHECKING:
from ..schema import SchemaVersion

from ..exception import MissingOptionalDependencyException
from ..schema._res import BOM_JSON as _S_BOM, BOM_JSON_STRICT as _S_BOM_STRICT, JSF as _S_JSF, SPDX_JSON as _S_SPDX
from . import MissingOptionalDependencyException, ValidationError, _BaseValidator
from . import ValidationError, _BaseValidator

_missing_deps_error: Optional[Tuple[MissingOptionalDependencyException, ImportError]] = None
try:
Expand All @@ -39,7 +43,16 @@
), err


class __BaseJsonValidator(_BaseValidator, ABC):
class _BaseJsonValidator(_BaseValidator, ABC):

def __init__(self, schema_version: 'SchemaVersion') -> None:
# this is the def that is used for generating the documentation
super().__init__(schema_version)

def validate_str(self, data: str) -> Optional[ValidationError]:
"""Validate a string according to the schema version."""
# this is the def that is used for generating the documentation

if _missing_deps_error:
__MDERROR = _missing_deps_error

Expand Down Expand Up @@ -84,15 +97,20 @@ def __make_validator_registry() -> Registry[Any]:
])


class JsonValidator(__BaseJsonValidator):
class JsonValidator(_BaseJsonValidator):
"""Validator for CycloneDX documents in JSON format."""

@property
def _schema_file(self) -> Optional[str]:
return _S_BOM.get(self.schema_version)


class JsonStrictValidator(__BaseJsonValidator):
class JsonStrictValidator(_BaseJsonValidator):
"""Strict validator for CycloneDX documents in JSON format.
In contrast to :class:`~JsonValidator`,
the document must not have additional or unknown JSON properties.
"""
@property
def _schema_file(self) -> Optional[str]:
return _S_BOM_STRICT.get(self.schema_version)
23 changes: 19 additions & 4 deletions cyclonedx/validation/xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@
__all__ = ['XmlValidator']

from abc import ABC
from typing import Any, Optional, Tuple
from typing import TYPE_CHECKING, Any, Optional, Tuple

from ..exception import MissingOptionalDependencyException
from ..schema._res import BOM_XML as _S_BOM
from . import MissingOptionalDependencyException, ValidationError, _BaseValidator
from . import ValidationError, _BaseValidator

if TYPE_CHECKING:
from ..schema import SchemaVersion

_missing_deps_error: Optional[Tuple[MissingOptionalDependencyException, ImportError]] = None
try:
Expand All @@ -32,7 +36,16 @@
), err


class __BaseXmlValidator(_BaseValidator, ABC):
class _BaseXmlValidator(_BaseValidator, ABC):

def __init__(self, schema_version: 'SchemaVersion') -> None:
# this is the def that is used for generating the documentation
super().__init__(schema_version)

def validate_str(self, data: str) -> Optional[ValidationError]:
"""Validate a string according to the schema version."""
# this is the def that is used for generating the documentation

if _missing_deps_error:
__MDERROR = _missing_deps_error

Expand Down Expand Up @@ -67,7 +80,9 @@ def _validator(self) -> 'XMLSchema':
return self.__validator


class XmlValidator(__BaseXmlValidator):
class XmlValidator(_BaseXmlValidator):
"""Validator for CycloneDX documents in XML format."""

@property
def _schema_file(self) -> Optional[str]:
return _S_BOM.get(self.schema_version)
5 changes: 4 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,18 @@
# ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.viewcode",
# "sphinx.ext.viewcode",
"autoapi.extension",
"sphinx_rtd_theme",
"m2r2"
]


# Document Python Code
autoapi_type = 'python'
autoapi_dirs = ['../cyclonedx']
# see https://sphinx-autoapi.readthedocs.io/en/latest/reference/config.html#confval-autoapi_options
autoapi_options = ['show-module-summary', 'members', 'undoc-members', 'inherited-members', 'show-inheritance']

source_suffix = ['.rst', '.md']

Expand Down
84 changes: 1 addition & 83 deletions docs/contributing.rst
Original file line number Diff line number Diff line change
@@ -1,83 +1 @@
Contributing
====================================================

Pull requests are welcome, but please read these contributing guidelines first.

Setup
----------------------------------------------------

This project uses `poetry`_. Have it installed and setup first.

To install dev-dependencies and tools:

.. code-block::
poetry install --all-extras
Code style
----------------------------------------------------

This project uses `PEP8`_ Style Guide for Python Code. This project loves sorted imports. Get it all applied via:

.. code-block::
poetry run isort .
poetry run autopep8 -ir cyclonedx/ tests/ typings/ examples/
Documentation
----------------------------------------------------

This project uses `Sphinx`_ to generate documentation which is automatically published to `readthedocs.io`_.

Source for documentation is stored in the ``docs`` folder in `RST`_ format.

You can generate the documentation locally by running:

.. code-block::
cd docs
pip install -r requirements.txt
make html
Testing
----------------------------------------------------

Run all tests in dedicated environments, via:

.. code-block::
poetry run tox run
Sign your commits
----------------------------------------------------

Please sign your commits, to show that you agree to publish your changes under the current terms and licenses of the
project. We can't accept contributions, however great, if you do not sign your commits.

.. code-block::
git commit --signed-off ...
Pre-commit hooks
----------------------------------------------------

If you like to take advantage of `pre-commit hooks`_, you can do so to cover most of the topics on this page when
contributing.

.. code-block::
pre-commit install
All our pre-commit checks will run locally before you can commit!


.. _poetry: https://python-poetry.org
.. _PEP8: https://www.python.org/dev/peps/pep-0008
.. _Sphinx: https://www.sphinx-doc.org/
.. _readthedocs.io: https://cyclonedx-python-library.readthedocs.io/
.. _RST: https://en.wikipedia.org/wiki/ReStructuredText
.. _pre-commit hooks: https://pre-commit.com
.. mdinclude:: ../CONTRIBUTING.md
6 changes: 3 additions & 3 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
m2r2>=0.3.2
Sphinx>=4.3.2
sphinx-autoapi>=1.8.4
sphinx-rtd-theme>=1.0.0
Sphinx>=7.2.6,<8
sphinx-autoapi>=2.1.1,<3
sphinx-rtd-theme>=1.3.0,<2
5 changes: 3 additions & 2 deletions examples/complex.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import sys

from packageurl import PackageURL

from cyclonedx.exception import MissingOptionalDependencyException
from cyclonedx.factory.license import LicenseChoiceFactory, LicenseFactory
from cyclonedx.model import OrganizationalEntity, XsUri
from cyclonedx.model.bom import Bom
from cyclonedx.model.component import Component, ComponentType
from cyclonedx.output.json import JsonV1Dot4
from cyclonedx.output.xml import XmlV1Dot4
from cyclonedx.schema import SchemaVersion
from cyclonedx.validation import MissingOptionalDependencyException
from cyclonedx.validation.json import JsonValidator
from cyclonedx.validation.xml import XmlValidator
from packageurl import PackageURL

lc_factory = LicenseChoiceFactory(license_factory=LicenseFactory())

Expand Down
2 changes: 1 addition & 1 deletion tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
from xmldiff import main
from xmldiff.actions import MoveNode

from cyclonedx.exception import MissingOptionalDependencyException
from cyclonedx.output import SchemaVersion
from cyclonedx.validation import MissingOptionalDependencyException
from cyclonedx.validation.json import JsonValidator
from cyclonedx.validation.xml import XmlValidator

Expand Down
2 changes: 1 addition & 1 deletion tests/test_validation_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@

from ddt import data, ddt, idata, unpack

from cyclonedx.exception import MissingOptionalDependencyException
from cyclonedx.schema import SchemaVersion
from cyclonedx.validation import MissingOptionalDependencyException
from cyclonedx.validation.json import JsonStrictValidator, JsonValidator

from . import TESTDATA_DIRECTORY
Expand Down

0 comments on commit 82d7cbf

Please sign in to comment.