@@ -96,8 +96,8 @@ def resolve_purl(purl):
9696 """
9797 Resolve a Package URL (PURL) to a download URL.
9898
99- This function attempts to resolve the PURL using both the purl2url library and
100- the fetchcode.download_urls module. It returns the first valid download URL found .
99+ This function attempts to resolve the PURL using first purl2url library and
100+ if that fails, it falls back to fetchcode's download_urls module .
101101 """
102102 from fetchcode .download_urls import download_url as get_download_url_from_fetchcode
103103
@@ -107,18 +107,47 @@ def resolve_purl(purl):
107107 return url
108108
109109
110+ def get_resolved_url (url , scheme ):
111+ resoltion_by_scheme = {
112+ "pkg" : resolve_url_from_purl ,
113+ }
114+ resolution_handler = resoltion_by_scheme .get (scheme )
115+ if not resolution_handler :
116+ raise ValueError (f"Not a supported/known scheme: { scheme } " )
117+ url , scheme = resolution_handler (url )
118+ return url , scheme
119+
120+
121+ def resolve_url_from_purl (url ):
122+ """
123+ Resolve a Package URL (PURL) to a valid URL.
124+ Raises ValueError if the PURL cannot be resolved.
125+ """
126+ url = resolve_purl (url )
127+ if not url :
128+ raise ValueError ("Could not resolve PURL to a valid URL." )
129+ scheme = get_url_scheme (url )
130+ return url , scheme
131+
132+
133+ def get_url_scheme (url ):
134+ """
135+ Return the scheme of the given URL.
136+ """
137+ url_parts = urlparse (url )
138+ scheme = url_parts .scheme
139+ return scheme
140+
141+
110142def fetch (url ):
111143 """
112144 Return a `Response` object built from fetching the content at the `url` URL string and
113145 store content at a temporary file.
114146 """
115- url_parts = urlparse (url )
116- scheme = url_parts .scheme
147+ scheme = get_url_scheme (url )
117148
118- if scheme == "pkg" :
119- url = resolve_purl (url )
120- url_parts = urlparse (url )
121- scheme = url_parts .scheme
149+ if scheme in ["pkg" ]:
150+ url , scheme = get_resolved_url (url , scheme )
122151
123152 temp = tempfile .NamedTemporaryFile (delete = False )
124153 location = temp .name
@@ -128,7 +157,7 @@ def fetch(url):
128157 if scheme in fetchers :
129158 return fetchers .get (scheme )(url , location )
130159
131- raise Exception ("Not a supported/known scheme." )
160+ raise Exception (f "Not a supported/known scheme: { scheme } ." )
132161
133162
134163def fetch_json_response (url ):
0 commit comments