@@ -527,6 +527,50 @@ def build_luarocks_download_url(purl):
527527 return f"https://luarocks.org/{ name } -{ version } .src.rock"
528528
529529
530+ @download_router .route ("pkg:conda/.*" )
531+ def build_conda_download_url (purl ):
532+ """
533+ Resolve a Conda PURL to a real downloadable URL
534+
535+ Supported qualifiers:
536+ - channel: e.g., main, conda-forge (required for deterministic base)
537+ - subdir: e.g., linux-64, osx-arm64, win-64, noarch
538+ - build: exact build string (optional but recommended)
539+ - type: 'conda' or 'tar.bz2' (preference; fallback to whichever exists)
540+ """
541+ p = PackageURL .from_string (purl )
542+ if not p .name or not p .version :
543+ return None
544+
545+ q = p .qualifiers or {}
546+ name = p .name
547+ version = p .version
548+ build = q .get ("build" )
549+ channel = q .get ("channel" ) or "main"
550+ subdir = q .get ("subdir" ) or "noarch"
551+ req_type = q .get ("type" )
552+
553+ def _conda_base_for_channel (channel : str ) -> str :
554+ """
555+ Map a conda channel to its base URL.
556+ - 'main' / 'defaults' -> repo.anaconda.com
557+ - any other channel -> conda.anaconda.org/<channel>
558+ """
559+ ch = (channel or "" ).lower ()
560+ if ch in ("main" , "defaults" ):
561+ return "https://repo.anaconda.com/pkgs/main"
562+ return f"https://conda.anaconda.org/{ ch } "
563+
564+ base = _conda_base_for_channel (channel )
565+
566+ package_identifier = (
567+ f"{ name } -{ version } -{ build } .{ req_type } " if build else f"{ name } -{ version } .{ req_type } "
568+ )
569+
570+ download_url = f"{ base } /{ subdir } /{ package_identifier } "
571+ return download_url
572+
573+
530574def get_repo_download_url (purl ):
531575 """
532576 Return ``download_url`` if present in ``purl`` qualifiers or
0 commit comments