diff --git a/CHANGELOG.rst b/CHANGELOG.rst index ffb868e..43181c1 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,12 @@ Changelog ========= +0.13.3 (2024-01-04) +------------------- + +- Improve support for SourceForge URLs in `url2purl`. + https://github.com/package-url/packageurl-python/issues/139 + 0.13.2 (2024-01-04) ------------------- diff --git a/README.rst b/README.rst index 10e8a1c..91b0861 100644 --- a/README.rst +++ b/README.rst @@ -121,7 +121,7 @@ Make a new release git tag -a $VERSION -m "Tag $VERSION" git push origin $VERSION -- Review and publish the "draft" release created by the workflow at +- 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 diff --git a/setup.cfg b/setup.cfg index 20d3c22..69af2d4 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = packageurl-python -version = 0.13.2 +version = 0.13.3 license = MIT description = A purl aka. Package URL parser and builder long_description = file:README.rst diff --git a/src/packageurl/contrib/url2purl.py b/src/packageurl/contrib/url2purl.py index d1d2034..d41e17e 100644 --- a/src/packageurl/contrib/url2purl.py +++ b/src/packageurl/contrib/url2purl.py @@ -344,7 +344,24 @@ def build_pypi_purl(uri): register_pattern("nuget", nuget_api_pattern) -@purl_router.route("https?://.*sourceforge.net/projects?/.*") +# https://sourceforge.net/projects/turbovnc/files/3.1/turbovnc-3.1.tar.gz/download +# https://sourceforge.net/projects/scribus/files/scribus/1.6.0/scribus-1.6.0.tar.gz/download +# https://sourceforge.net/projects/ventoy/files/v1.0.96/Ventoy%201.0.96%20release%20source%20code.tar.gz/download +# https://sourceforge.net/projects/geoserver/files/GeoServer/2.23.4/geoserver-2.23.4-war.zip/download +sourceforge_download_pattern = ( + r"^https?://.*sourceforge.net/projects/" + r"(?P.+)/" + r"files/" + r"(?i:(?P=name)/)?" # optional case-insensitive name segment repeated + r"v?(?P[0-9\.]+)/" # version restricted to digits and dots + r"(?i:(?P=name)).*(?P=version).*" # case-insensitive matching for {name}-{version} + r"(/download)$" # ending with "/download" +) + +register_pattern("sourceforge", sourceforge_download_pattern) + + +@purl_router.route("https?://.*sourceforge.net/project/.*") def build_sourceforge_purl(uri): # We use a more general route pattern instead of using `sourceforge_pattern` # below by itself because we want to capture all sourceforge download URLs, @@ -353,14 +370,13 @@ def build_sourceforge_purl(uri): # URL that we can't handle. # http://master.dl.sourceforge.net/project/libpng/zlib/1.2.3/zlib-1.2.3.tar.bz2 - # https://sourceforge.net/projects/scribus/files/scribus/1.6.0/scribus-1.6.0.tar.gz/download sourceforge_pattern = ( r"^https?://.*sourceforge.net/projects?/" r"(?P([^/]+))/" # do not allow more "/" segments - r"(files/)?" # optional segment for "*/download" type URLs + r"(OldFiles/)?" r"(?P.+)/" - r"(?P[0-9\.]+)/" # version restricted to digits and dots - r"(?P=name)-(?P=version).*" # {name}-{version} repeated in the filename + r"(?P[v0-9\.]+)/" # version restricted to digits and dots + r"(?P=name).*(?P=version).*" # {name}-{version} repeated in the filename r"[^/]$" # not ending with "/" ) diff --git a/tests/contrib/data/url2purl.json b/tests/contrib/data/url2purl.json index ddc43ed..999571b 100644 --- a/tests/contrib/data/url2purl.json +++ b/tests/contrib/data/url2purl.json @@ -160,18 +160,21 @@ "http://master.dl.sourceforge.net/project/zinnia/zinnia-win32/0.06/zinnia-win32-0.06.zip": "pkg:sourceforge/zinnia/zinnia-win32@0.06", "http://iweb.dl.sourceforge.net/project/findbugs/findbugs/1.3.4/findbugs-1.3.4.tar.gz/": "pkg:sourceforge/findbugs?download_url=http://iweb.dl.sourceforge.net/project/findbugs/findbugs/1.3.4/findbugs-1.3.4.tar.gz/", "http://master.dl.sourceforge.net/project/arestc/net/sf/arestc/arestc/0.1.4/arestc-0.1.4-javadoc.jar": "pkg:sourceforge/arestc?download_url=http://master.dl.sourceforge.net/project/arestc/net/sf/arestc/arestc/0.1.4/arestc-0.1.4-javadoc.jar", - "http://master.dl.sourceforge.net/project/intraperson/OldFiles/intraperson/0.28/intraperson-0.28.tar.gz": "pkg:sourceforge/intraperson?download_url=http://master.dl.sourceforge.net/project/intraperson/OldFiles/intraperson/0.28/intraperson-0.28.tar.gz", + "http://master.dl.sourceforge.net/project/intraperson/OldFiles/intraperson/0.28/intraperson-0.28.tar.gz": "pkg:sourceforge/intraperson/intraperson@0.28", "http://master.dl.sourceforge.net/project/pwiki/pwiki/0.1.2/0.1.2.zip": "pkg:sourceforge/pwiki?download_url=http://master.dl.sourceforge.net/project/pwiki/pwiki/0.1.2/0.1.2.zip", "http://master.dl.sourceforge.net/project/iswraid/iswraid/0.1.4.3/2.4.28-pre3-iswraid.patch.gz": "pkg:sourceforge/iswraid?download_url=http://master.dl.sourceforge.net/project/iswraid/iswraid/0.1.4.3/2.4.28-pre3-iswraid.patch.gz", "http://master.dl.sourceforge.net/project/aloyscore/aloyscore/0.1a1%20stable/0.1a1_stable_AloysCore.zip": "pkg:sourceforge/aloyscore?download_url=http://master.dl.sourceforge.net/project/aloyscore/aloyscore/0.1a1%2520stable/0.1a1_stable_AloysCore.zip", "http://master.dl.sourceforge.net/project/myenterprise/OldFiles/1.0.0.2.MyEnterprise.Source.zip": "pkg:sourceforge/myenterprise?download_url=http://master.dl.sourceforge.net/project/myenterprise/OldFiles/1.0.0.2.MyEnterprise.Source.zip", "http://master.dl.sourceforge.net/project/wxhaskell/wxhaskell/wxhaskell-0.9/wxhaskell-src-0.9.zip": "pkg:sourceforge/wxhaskell?download_url=http://master.dl.sourceforge.net/project/wxhaskell/wxhaskell/wxhaskell-0.9/wxhaskell-src-0.9.zip", "http://master.dl.sourceforge.net/project/a2freedom/A2/1.2/a2freedom-1.2.zip": "pkg:sourceforge/a2freedom?download_url=http://master.dl.sourceforge.net/project/a2freedom/A2/1.2/a2freedom-1.2.zip", - "http://master.dl.sourceforge.net/project/tinyos/OldFiles/tinyos/1.1.0/tinyos-1.1.0.tar.gz": "pkg:sourceforge/tinyos?download_url=http://master.dl.sourceforge.net/project/tinyos/OldFiles/tinyos/1.1.0/tinyos-1.1.0.tar.gz", + "http://master.dl.sourceforge.net/project/tinyos/OldFiles/tinyos/1.1.0/tinyos-1.1.0.tar.gz": "pkg:sourceforge/tinyos/tinyos@1.1.0", "http://master.dl.sourceforge.net/project/urlchecker/lu/ng/urlchecker/urlchecker/1.7/urlchecker-1.7-javadoc.jar": "pkg:sourceforge/urlchecker?download_url=http://master.dl.sourceforge.net/project/urlchecker/lu/ng/urlchecker/urlchecker/1.7/urlchecker-1.7-javadoc.jar", "http://master.dl.sourceforge.net/project/zclasspath/maven2/org/zclasspath/zclasspath/1.5/zclasspath-1.5.jar": "pkg:sourceforge/zclasspath?download_url=http://master.dl.sourceforge.net/project/zclasspath/maven2/org/zclasspath/zclasspath/1.5/zclasspath-1.5.jar", "http://master.dl.sourceforge.net/project/googleimagedown/project/v1.1/GoogleImageDownloader-v1.1-src.tar.bz2": "pkg:sourceforge/googleimagedown?download_url=http://master.dl.sourceforge.net/project/googleimagedown/project/v1.1/GoogleImageDownloader-v1.1-src.tar.bz2", - "https://sourceforge.net/projects/scribus/files/scribus/1.6.0/scribus-1.6.0.tar.gz/download": "pkg:sourceforge/scribus/scribus@1.6.0", + "https://sourceforge.net/projects/scribus/files/scribus/1.6.0/scribus-1.6.0.tar.gz/download": "pkg:sourceforge/scribus@1.6.0", + "https://sourceforge.net/projects/turbovnc/files/3.1/turbovnc-3.1.tar.gz/download": "pkg:sourceforge/turbovnc@3.1", + "https://sourceforge.net/projects/ventoy/files/v1.0.96/Ventoy%201.0.96%20release%20source%20code.tar.gz/download": "pkg:sourceforge/ventoy@1.0.96", + "https://sourceforge.net/projects/geoserver/files/GeoServer/2.23.4/geoserver-2.23.4-war.zip/download": "pkg:sourceforge/geoserver@2.23.4", "https://crates.io/api/v1/crates/rand/0.7.2/download": "pkg:cargo/rand@0.7.2", "https://crates.io/api/v1/crates/clap/2.33.0/download": "pkg:cargo/clap@2.33.0", "https://crates.io/api/v1/crates/structopt/0.3.11/download": "pkg:cargo/structopt@0.3.11",