=================
packageurl-python
=================

Python library to parse and build "purl" aka. Package URLs.
See https://github.com/package-url/purl-spec for details.

Join the discussion at https://gitter.im/package-url/Lobby or enter a ticket for support.

License: MIT

Tests and build status
======================

+----------------------+
| **Tests and build**  |
+======================+
| |ci-tests|           |
+----------------------+

Install
=======
::

    pip install packageurl-python

Usage
=====
::

    >>> from packageurl import PackageURL

    >>> purl = PackageURL.from_string("pkg:maven/org.apache.commons/io@1.3.4")
    >>> print(purl.to_dict())
    {'type': 'maven', 'namespace': 'org.apache.commons', 'name': 'io', 'version': '1.3.4', 'qualifiers': None, 'subpath': None}

    >>> print(purl.to_string())
    pkg:maven/org.apache.commons/io@1.3.4

    >>> print(str(purl))
    pkg:maven/org.apache.commons/io@1.3.4

    >>> print(repr(purl))
    PackageURL(type='maven', namespace='org.apache.commons', name='io', version='1.3.4', qualifiers={}, subpath=None)

Utilities
=========

Django models
^^^^^^^^^^^^^

`packageurl.contrib.django.models.PackageURLMixin` is a Django abstract model mixin to
use Package URLs in Django.

SQLAlchemy mixin
^^^^^^^^^^^^^^^^

`packageurl.contrib.sqlalchemy.mixin.PackageURLMixin` is a SQLAlchemy declarative mixin
to use Package URLs in SQLAlchemy models.

URL to PURL
^^^^^^^^^^^

`packageurl.contrib.url2purl.get_purl(url)` returns a Package URL inferred from an URL.

::

    >>> from packageurl.contrib import url2purl
    >>> url2purl.get_purl("https://github.com/package-url/packageurl-python")
    PackageURL(type='github', namespace='package-url', name='packageurl-python', version=None, qualifiers={}, subpath=None)

PURL to URL
^^^^^^^^^^^

- `packageurl.contrib.purl2url.get_repo_url(purl)` returns a repository URL inferred
  from a Package URL.
- `packageurl.contrib.purl2url.get_download_url(purl)` returns a download URL inferred
  from a Package URL.
- `packageurl.contrib.purl2url.get_inferred_urls(purl)` return all inferred URLs
  (repository, download) from a Package URL.

::

    >>> from packageurl.contrib import purl2url

    >>> purl2url.get_repo_url("pkg:gem/bundler@2.3.23")
    "https://rubygems.org/gems/bundler/versions/2.3.23"

    >>> purl2url.get_download_url("pkg:gem/bundler@2.3.23")
    "https://rubygems.org/downloads/bundler-2.3.23.gem"

    >>> purl2url.get_inferred_urls("pkg:gem/bundler@2.3.23")
    ["https://rubygems.org/gems/bundler/versions/2.3.23", "https://rubygems.org/downloads/bundler-2.3.23.gem"]

Run tests
=========

Install test dependencies::

    python3 thirdparty/virtualenv.pyz --never-download --no-periodic-update .
    bin/pip install -e ."[test]"

Run tests::

    bin/pytest tests

Make a new release
==================

- Start a new release branch
- Update the CHANGELOG.rst, AUTHORS.rst, and README.rst if needed
- Bump version in setup.cfg
- Run all tests
- Install restview and validate that all .rst docs are correct
- Commit and push this branch
- Make a PR and merge once approved
- Tag and push that tag. This triggers the pypi-release.yml workflow that takes care of
  building the dist release files and upload those to pypi::

    VERSION=v0.x.x
    git tag -a $VERSION -m "Tag $VERSION"
    git push origin $VERSION

- Review the GitHub release created by the workflow at
  https://github.com/package-url/packageurl-python/releases

.. |ci-tests| image:: https://github.com/package-url/packageurl-python/actions/workflows/ci.yml/badge.svg?branch=main
    :target: https://github.com/package-url/packageurl-python/actions/workflows/ci.yml
    :alt: CI Tests and build status
