1515import attr
1616from license_expression import Licensing
1717
18+ from commoncode import filetype
1819from packagedcode import models
1920from packagedcode import nevra
2021from packagedcode .pyrpm import RPM
@@ -73,11 +74,6 @@ def get_rpm_tags(location, include_desc=False):
7374 Return an RPMtags object for the file at location or None.
7475 Include the long RPM description value if `include_desc` is True.
7576 """
76- T = typecode .contenttype .get_type (location )
77-
78- if 'rpm' not in T .filetype_file .lower ():
79- return
80-
8177 with open (location , 'rb' ) as rpmf :
8278 rpm = RPM (rpmf )
8379 tags = {k : v for k , v in rpm .to_dict ().items () if k in RPM_TAGS }
@@ -117,8 +113,7 @@ def to_string(self):
117113
118114@attr .s ()
119115class RpmPackage (models .Package , models .PackageManifest ):
120- file_patterns = ('*.spec' ,)
121- extensions = ('.rpm' , '.srpm' , '.mvl' , '.vip' ,)
116+
122117 filetypes = ('rpm ' ,)
123118 mimetypes = ('application/x-rpm' ,)
124119
@@ -128,10 +123,6 @@ class RpmPackage(models.Package, models.PackageManifest):
128123 default_download_baseurl = None
129124 default_api_baseurl = None
130125
131- @classmethod
132- def recognize (cls , location ):
133- yield parse (location )
134-
135126 def compute_normalized_license (self ):
136127 _declared , detected = detect_declared_license (self .declared_license )
137128 return detected
@@ -164,82 +155,103 @@ def get_installed_packages(root_dir, detect_licenses=False, **kwargs):
164155 return rpm_installed .parse_rpm_xmlish (xmlish_loc , detect_licenses = detect_licenses )
165156
166157
167- def parse (location ):
168- """
169- Return an RpmPackage object for the file at location or None if
170- the file is not an RPM.
171- """
172- rpm_tags = get_rpm_tags (location , include_desc = True )
173- return build_from_tags (rpm_tags )
158+ @attr .s ()
159+ class RPMManifest (RpmPackage , models .PackageManifest ):
174160
161+ file_patterns = ('*.spec' ,)
162+ extensions = ('.rpm' , '.srpm' , '.mvl' , '.vip' ,)
163+ manifest_type = 'rpmmanifest'
175164
176- def build_from_tags (rpm_tags ):
177- """
178- Return an RpmPackage object from an ``rpm_tags`` RPMtags object.
179- """
180- if TRACE : logger_debug ('build_from_tags: rpm_tags' , rpm_tags )
181- if not rpm_tags :
182- return
183-
184- name = rpm_tags .name
185-
186- try :
187- epoch = rpm_tags .epoch and int (rpm_tags .epoch ) or None
188- except ValueError :
189- epoch = None
190-
191- evr = EVR (
192- version = rpm_tags .version or None ,
193- release = rpm_tags .release or None ,
194- epoch = epoch ).to_string ()
195-
196- qualifiers = {}
197- os = rpm_tags .os
198- if os and os .lower () != 'linux' :
199- qualifiers ['os' ] = os
200-
201- arch = rpm_tags .arch
202- if arch :
203- qualifiers ['arch' ] = arch
204-
205- source_packages = []
206- if rpm_tags .source_rpm :
207- sepoch , sname , sversion , srel , sarch = nevra .from_name (rpm_tags .source_rpm )
208- src_evr = EVR (sversion , srel , sepoch ).to_string ()
209- src_qualifiers = {}
210- if sarch :
211- src_qualifiers ['arch' ] = sarch
212-
213- src_purl = models .PackageURL (
214- type = RpmPackage .default_type ,
215- name = sname ,
216- version = src_evr ,
217- qualifiers = src_qualifiers
218- ).to_string ()
219-
220- if TRACE : logger_debug ('build_from_tags: source_rpm' , src_purl )
221- source_packages = [src_purl ]
222-
223- parties = []
224-
225- # TODO: also use me to craft a namespace!!!
226- # TODO: assign a namepsace to Package URL based on distro names.
227- # CentOS
228- # Fedora Project
229- # OpenMandriva Lx
230- # openSUSE Tumbleweed
231- # Red Hat
232-
233- if rpm_tags .distribution :
234- parties .append (models .Party (name = rpm_tags .distribution , role = 'distributor' ))
235-
236- if rpm_tags .vendor :
237- parties .append (models .Party (name = rpm_tags .vendor , role = 'vendor' ))
238-
239- description = build_description (rpm_tags .summary , rpm_tags .description )
240-
241- if TRACE :
242- data = dict (
165+ @classmethod
166+ def is_manifest (cls , location ):
167+ """
168+ Return True if the file at ``location`` is likely a manifest of this type.
169+ """
170+ T = typecode .contenttype .get_type (location )
171+ return (filetype .is_file (location ) and 'rpm' in T .filetype_file .lower ())
172+
173+ @classmethod
174+ def recognize (cls , location ):
175+ """
176+ Yield one or more Package manifest objects given a file ``location`` pointing to a
177+ package archive, manifest or similar.
178+ """
179+ rpm_tags = get_rpm_tags (location , include_desc = True )
180+
181+ if TRACE : logger_debug ('build_from_tags: rpm_tags' , rpm_tags )
182+ if not rpm_tags :
183+ return
184+
185+ name = rpm_tags .name
186+
187+ try :
188+ epoch = rpm_tags .epoch and int (rpm_tags .epoch ) or None
189+ except ValueError :
190+ epoch = None
191+
192+ evr = EVR (
193+ version = rpm_tags .version or None ,
194+ release = rpm_tags .release or None ,
195+ epoch = epoch ).to_string ()
196+
197+ qualifiers = {}
198+ os = rpm_tags .os
199+ if os and os .lower () != 'linux' :
200+ qualifiers ['os' ] = os
201+
202+ arch = rpm_tags .arch
203+ if arch :
204+ qualifiers ['arch' ] = arch
205+
206+ source_packages = []
207+ if rpm_tags .source_rpm :
208+ sepoch , sname , sversion , srel , sarch = nevra .from_name (rpm_tags .source_rpm )
209+ src_evr = EVR (sversion , srel , sepoch ).to_string ()
210+ src_qualifiers = {}
211+ if sarch :
212+ src_qualifiers ['arch' ] = sarch
213+
214+ src_purl = models .PackageURL (
215+ type = RpmPackage .default_type ,
216+ name = sname ,
217+ version = src_evr ,
218+ qualifiers = src_qualifiers
219+ ).to_string ()
220+
221+ if TRACE : logger_debug ('build_from_tags: source_rpm' , src_purl )
222+ source_packages = [src_purl ]
223+
224+ parties = []
225+
226+ # TODO: also use me to craft a namespace!!!
227+ # TODO: assign a namepsace to Package URL based on distro names.
228+ # CentOS
229+ # Fedora Project
230+ # OpenMandriva Lx
231+ # openSUSE Tumbleweed
232+ # Red Hat
233+
234+ if rpm_tags .distribution :
235+ parties .append (models .Party (name = rpm_tags .distribution , role = 'distributor' ))
236+
237+ if rpm_tags .vendor :
238+ parties .append (models .Party (name = rpm_tags .vendor , role = 'vendor' ))
239+
240+ description = build_description (rpm_tags .summary , rpm_tags .description )
241+
242+ if TRACE :
243+ data = dict (
244+ name = name ,
245+ version = evr ,
246+ description = description or None ,
247+ homepage_url = rpm_tags .url or None ,
248+ parties = parties ,
249+ declared_license = rpm_tags .license or None ,
250+ source_packages = source_packages ,
251+ )
252+ logger_debug ('build_from_tags: data to create a package:\n ' , data )
253+
254+ package = cls (
243255 name = name ,
244256 version = evr ,
245257 description = description or None ,
@@ -248,22 +260,11 @@ def build_from_tags(rpm_tags):
248260 declared_license = rpm_tags .license or None ,
249261 source_packages = source_packages ,
250262 )
251- logger_debug ('build_from_tags: data to create a package:\n ' , data )
252-
253- package = RpmPackage (
254- name = name ,
255- version = evr ,
256- description = description or None ,
257- homepage_url = rpm_tags .url or None ,
258- parties = parties ,
259- declared_license = rpm_tags .license or None ,
260- source_packages = source_packages ,
261- )
262-
263- if TRACE :
264- logger_debug ('build_from_tags: created package:\n ' , package )
265-
266- return package
263+
264+ if TRACE :
265+ logger_debug ('build_from_tags: created package:\n ' , package )
266+
267+ return package
267268
268269############################################################################
269270# FIXME: this license detection code is mostly copied from debian_copyright.py and alpine.py
0 commit comments