@@ -99,9 +99,18 @@ def _create_dependent_package(cls, dep_components):
9999 version_number = dep_components .get ('version_number' )
100100 version_spec = dep_components .get ('version_spec' )
101101
102- purl_str = cls ._create_purl_string (name , version_number )
103- # Determine if pinned (exact version with == operator)
104- is_pinned = bool (version_spec and '==' in str (version_spec ))
102+ # Determine if pinned (exact version with == operator or no operator)
103+ is_pinned = False
104+ if version_spec :
105+ v_spec_str = str (version_spec ).strip ()
106+ if '==' in v_spec_str :
107+ is_pinned = True
108+ elif v_spec_str == version_number :
109+ is_pinned = True
110+
111+ # Only include version in PURL if pinned
112+ purl_version = version_number if is_pinned else None
113+ purl_str = cls ._create_purl_string (name , purl_version )
105114
106115 return models .DependentPackage (
107116 purl = purl_str ,
@@ -174,6 +183,7 @@ def __init__(self, rockspec_path):
174183 self .rockspec_path = rockspec_path
175184 self .ast_tree = None
176185 self .errors = []
186+ self ._description_table = None
177187
178188 def parse (self ):
179189 """Read file, parse AST, extract all rockspec fields and return data dict."""
@@ -215,6 +225,20 @@ def _parse_lua(self, code):
215225 except Exception as e :
216226 raise RuntimeError (f"Lua parse error: { e } " )
217227
228+ def _get_description_table (self ):
229+ """Return the description table as a dict if present."""
230+ if self ._description_table is not None :
231+ return self ._description_table
232+
233+ assignment = self ._find_assignment ('description' )
234+ if not assignment :
235+ self ._description_table = {}
236+ else :
237+ _ , value = assignment
238+ self ._description_table = self ._extract_table_values (value )
239+
240+ return self ._description_table
241+
218242 def _find_assignment (self , var_name ):
219243 """Return (target_node, value_node) tuple for variable assignment or None."""
220244 if not self .ast_tree :
@@ -445,38 +469,28 @@ def _extract_source_url(self):
445469 return str (source_url )
446470
447471 def _extract_description (self ):
448- """Extract and return optional description.summary field ."""
449- assignment = self ._find_assignment ( 'description' )
450- if not assignment :
451- return None
472+ """Extract and return combined optional description fields ."""
473+ desc_table = self ._get_description_table ( )
474+ summary = desc_table . get ( 'summary' )
475+ detailed = desc_table . get ( 'detailed' )
452476
453- _ , value = assignment
454- desc_table = self ._extract_table_values (value )
477+ parts = []
478+ if summary :
479+ parts .append (str (summary ).strip ())
480+ if detailed :
481+ parts .append (str (detailed ).strip ())
455482
456- summary = desc_table .get ('summary' )
457- return str (summary ) if summary else None
483+ return '\n ' .join (parts ) if parts else None
458484
459485 def _extract_license (self ):
460486 """Extract and return optional license field from description table."""
461- assignment = self ._find_assignment ('description' )
462- if not assignment :
463- return None
464-
465- _ , value = assignment
466- desc_table = self ._extract_table_values (value )
467-
487+ desc_table = self ._get_description_table ()
468488 license_val = desc_table .get ('license' )
469489 return str (license_val ) if license_val else None
470490
471491 def _extract_homepage (self ):
472492 """Extract and return optional homepage URL from description table."""
473- assignment = self ._find_assignment ('description' )
474- if not assignment :
475- return None
476-
477- _ , value = assignment
478- desc_table = self ._extract_table_values (value )
479-
493+ desc_table = self ._get_description_table ()
480494 homepage = desc_table .get ('homepage' )
481495 return str (homepage ) if homepage else None
482496
@@ -541,14 +555,11 @@ def parse_dependency(self, dep_string):
541555 version_spec = None
542556
543557 if version_raw :
544- version_raw = version_raw .strip ()
545- version_match = re .search (r'([0-9][0-9.]*)' , version_raw )
546- if version_match :
547- version_number = version_match .group (1 )
548- if operator :
549- version_spec = operator + ' ' + version_number
550- else :
551- version_spec = version_number
558+ version_number = version_raw .strip ()
559+ if operator :
560+ version_spec = f"{ operator } { version_number } "
561+ else :
562+ version_spec = version_number
552563
553564 return {
554565 'name' : name ,
0 commit comments