Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package product-composer for 
openSUSE:Factory checked in at 2023-12-06 23:47:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/product-composer (Old)
 and      /work/SRC/openSUSE:Factory/.product-composer.new.25432 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "product-composer"

Wed Dec  6 23:47:25 2023 rev:2 rq:1130998 version:0.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/product-composer/product-composer.changes        
2023-12-04 23:02:50.206543986 +0100
+++ 
/work/SRC/openSUSE:Factory/.product-composer.new.25432/product-composer.changes 
    2023-12-06 23:47:28.281591815 +0100
@@ -1,0 +2,6 @@
+Tue Dec  5 14:46:55 UTC 2023 - Adrian Schröter <[email protected]>
+
+- update to version 0.2
+  * Support .report file generation
+
+-------------------------------------------------------------------

Old:
----
  product-composer-0.1.obscpio

New:
----
  product-composer-0.2.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ product-composer.spec ++++++
--- /var/tmp/diff_new_pack.ucyY1r/_old  2023-12-06 23:47:29.065620719 +0100
+++ /var/tmp/diff_new_pack.ucyY1r/_new  2023-12-06 23:47:29.065620719 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           product-composer
-Version:        0.1
+Version:        0.2
 Release:        0
 Summary:        Product Composer
 License:        GPL-2.0-or-later
@@ -53,7 +53,7 @@
 mv %buildroot/usr/bin/productcomposer %buildroot%_bindir/product-composer
 
 %files
-%doc README.rst docs
+%doc README.rst docs examples
 %_bindir/product-composer
 %{python3_sitelib}/*
 

++++++ _service ++++++
--- /var/tmp/diff_new_pack.ucyY1r/_old  2023-12-06 23:47:29.089621603 +0100
+++ /var/tmp/diff_new_pack.ucyY1r/_new  2023-12-06 23:47:29.093621752 +0100
@@ -2,8 +2,8 @@
   <service name="obs_scm" mode="manual">
     <param name="url">https://github.com/openSUSE/product-composer</param>
     <param name="scm">git</param>
-    <param name="version">0.1</param>
-    <param name="revision">0.1</param>
+    <param name="version">0.2</param>
+    <param name="revision">0.2</param>
   </service>
   <service name="tar" mode="buildtime" />
   <service name="recompress" mode="buildtime">

++++++ product-composer-0.1.obscpio -> product-composer-0.2.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/product-composer-0.1/docs/build_description.adoc 
new/product-composer-0.2/docs/build_description.adoc
--- old/product-composer-0.1/docs/build_description.adoc        2023-12-04 
15:22:14.000000000 +0100
+++ new/product-composer-0.2/docs/build_description.adoc        2023-12-05 
15:36:06.000000000 +0100
@@ -52,7 +52,7 @@
 There is usually one master list and in addition there
 can be addional optional lists.
 
-The additional list can be filter by flavors and/or 
+The additional lists can be filtered by flavors and/or 
 architectures.
 
 ==== unpack_packages
@@ -116,6 +116,13 @@
 The package list can be valid global or for specific flavors
 or architectures only.
 
+The syntax is rpm like
+
+ [EPOCH:]VERSION[-RELEASE]
+
+So an epoch or a release can be specified optional. Otherwise
+any epoch or release is qualified.
+
 ==== product_compose_schema
 
 Defines the level of the yaml syntax. We are currently at level 0.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/product-composer-0.1/docs/productcomposer.adoc 
new/product-composer-0.2/docs/productcomposer.adoc
--- old/product-composer-0.1/docs/productcomposer.adoc  2023-12-04 
15:22:14.000000000 +0100
+++ new/product-composer-0.2/docs/productcomposer.adoc  2023-12-05 
15:36:06.000000000 +0100
@@ -11,19 +11,19 @@
 It is used to generate product rpm repositories out of a pool of rpms.
 Unlike product builder, these can also be used to ship maintenance updates.
 
-Currently it supports:
- - processing based on a list of rpm package names.
-   product compose is not take care of dependencies atm.
- - providing matching source and/or debug packages for picked rpm packages.
-   These can be either included into main repository or prepared via
-   extra repositories
- - optional filters for architectures, versions and flavors can be defined
- - it can provide either just a single rpm of a given name or all of them
- - it can post process updateinfo data
- - post processing to provide various rpm meta data generation
+.Currently it supports:
+- processing based on a list of rpm package names.
+  product compose is not take care of dependencies atm.
+- providing matching source and/or debug packages for picked rpm packages.
+  These can be either included into main repository or prepared via
+  extra repositories
+- optional filters for architectures, versions and flavors can be defined
+- it can provide either just a single rpm of a given name or all of them
+- it can post process updateinfo data
+- post processing to provide various rpm meta data generation
 
 Not yet implemented:
- - create bootable iso files
+- create bootable iso files
 
 == Design
 
@@ -35,10 +35,10 @@
 
 You will require OBS 2.11 or later.
 
-Create a new repository with any name. Either in a new or existing project.
- - The product-composer package must be available in any repository
-   listed in the path elements.
- - All scheduler architectures where packages are taken from must be listed.
+.Create a new repository with any name. Either in a new or existing project.
+- The product-composer package must be available in any repository
+  listed in the path elements.
+- All scheduler architectures where packages are taken from must be listed.
 
 Your build description file may have any name, but must have a .productcompose
 suffix.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/product-composer-0.1/docs/productcomposer.html 
new/product-composer-0.2/docs/productcomposer.html
--- old/product-composer-0.1/docs/productcomposer.html  2023-12-04 
15:22:14.000000000 +0100
+++ new/product-composer-0.2/docs/productcomposer.html  2023-12-05 
15:36:06.000000000 +0100
@@ -748,17 +748,17 @@
 <div class="paragraph"><p>It is used to generate product rpm repositories out 
of a pool of rpms.
 Unlike product builder, these can also be used to ship maintenance 
updates.</p></div>
 <div class="paragraph"><p>Currently it supports:
- - processing based on a list of rpm package names.
-   product compose is not take care of dependencies atm.
- - providing matching source and/or debug packages for picked rpm packages.
-   These can be either included into main repository or prepared via
-   extra repositories
- - optional filters for architectures, versions and flavors can be defined
- - it can provide either just a single rpm of a given name or all of them
- - it can post process updateinfo data
- - post processing to provide various rpm meta data generation</p></div>
+- processing based on a list of rpm package names.
+  product compose is not take care of dependencies atm.
+- providing matching source and/or debug packages for picked rpm packages.
+  These can be either included into main repository or prepared via
+  extra repositories
+- optional filters for architectures, versions and flavors can be defined
+- it can provide either just a single rpm of a given name or all of them
+- it can post process updateinfo data
+- post processing to provide various rpm meta data generation</p></div>
 <div class="paragraph"><p>Not yet implemented:
- - create bootable iso files</p></div>
+- create bootable iso files</p></div>
 </div>
 </div>
 <div class="sect1">
@@ -774,9 +774,9 @@
 <div class="sectionbody">
 <div class="paragraph"><p>You will require OBS 2.11 or later.</p></div>
 <div class="paragraph"><p>Create a new repository with any name. Either in a 
new or existing project.
- - The product-composer package must be available in any repository
-   listed in the path elements.
- - All scheduler architectures where packages are taken from must be 
listed.</p></div>
+- The product-composer package must be available in any repository
+  listed in the path elements.
+- All scheduler architectures where packages are taken from must be 
listed.</p></div>
 <div class="paragraph"><p>Your build description file may have any name, but 
must have a .productcompose
 suffix.</p></div>
 <div class="paragraph"><p>The build type for the repository must be set 
to</p></div>
@@ -833,7 +833,14 @@
 still listed in the build log.</p></div>
 </div>
 <div class="sect3">
-<h4 id="_flavors">5.2.3. flavors</h4>
+<h4 id="_hide_flavor_in_product_directory_name">5.2.3. 
hide_flavor_in_product_directory_name</h4>
+<div class="paragraph"><p>The flavor name is by default part of the directory
+name of the build result. This can be disabled,
+when each flavor has a different arch list. Otherwise
+conflicts can happen.</p></div>
+</div>
+<div class="sect3">
+<h4 id="_flavors">5.2.4. flavors</h4>
 <div class="paragraph"><p>Flavors can be defined with any name. These can be
 used to build multiple media from one build description.</p></div>
 <div class="paragraph"><p>Each flavor may define an own architecture 
list.</p></div>
@@ -842,15 +849,15 @@
 to enable the build.</p></div>
 </div>
 <div class="sect3">
-<h4 id="_packages">5.2.4. packages</h4>
+<h4 id="_packages">5.2.5. packages</h4>
 <div class="paragraph"><p>The packages list lists rpm names to be put on the 
medium.</p></div>
 <div class="paragraph"><p>There is usually one master list and in addition 
there
 can be addional optional lists.</p></div>
-<div class="paragraph"><p>The additional list can be filter by flavors and/or
+<div class="paragraph"><p>The additional lists can be filtered by flavors 
and/or
 architectures.</p></div>
 </div>
 <div class="sect3">
-<h4 id="_unpack_packages">5.2.5. unpack_packages</h4>
+<h4 id="_unpack_packages">5.2.6. unpack_packages</h4>
 <div class="paragraph"><p>The unpack_packages section can be used in the same 
way
 as the packages section.</p></div>
 <div class="paragraph"><p>The difference is that not the rpm itself is put
@@ -906,6 +913,13 @@
 specific versions.</p></div>
 <div class="paragraph"><p>The package list can be valid global or for specific 
flavors
 or architectures only.</p></div>
+<div class="paragraph"><p>The syntax is rpm like</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><code>[EPOCH:]VERSION[-RELEASE]</code></pre>
+</div></div>
+<div class="paragraph"><p>So an epoch or a release can be specified optional. 
Otherwise
+any epoch or release is qualified.</p></div>
 </div>
 <div class="sect3">
 <h4 id="_product_compose_schema">5.3.7. product_compose_schema</h4>
@@ -951,7 +965,7 @@
 <div id="footer">
 <div id="footer-text">
 Last updated
- 2023-11-30 15:49:31 CET
+ 2023-12-04 16:19:48 CET
 </div>
 </div>
 </body>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/product-composer-0.1/examples/ftp.obsproduct 
new/product-composer-0.2/examples/ftp.obsproduct
--- old/product-composer-0.1/examples/ftp.obsproduct    2023-12-04 
15:22:14.000000000 +0100
+++ new/product-composer-0.2/examples/ftp.obsproduct    1970-01-01 
01:00:00.000000000 +0100
@@ -1,67 +0,0 @@
-# Our initial schema version. Be prepared that it breaks until we are
-# in full production mode
-product_compose_schema: 0
-
-vendor: openSUSE
-name: Tumbleweed
-version: 1.0
-
-summary: openSUSE Tumbleweed
-description: >
-  openSUSE Tumbleweed is the rolling distribution by the
-  openSUSE.org project.
-
-
-build_options:
-### For maintenance, otherwise only "the best" version of each package is 
picked:
- - take_all_available_versions
-### do not abort on missing packages
- - ignore_missing_packages
-# - hide_flavor_in_product_directory_name
-
-# Enable collection of source and debug packages. Either "include" it
-# on main medium or "split" it away on extra medium.
-source: include
-debug: split
-
-# The default architecture list. Each of these will be put on the medium.
-# It is optional to have a default list, when each flavor defines an
-# architecture list. The main package won't be build in that case.
-architectures: [ x86_64 ]
-
-# A flavor list, each flavor may change the architecture list
-flavors:
-- small
-- large_arm:
-    architectures: [ armv7l, aarch64 ]
-
-# packages to be extracted
-unpack_packages:
- - flavors:
-    - DVD medium
-   architectures:
-    - ppc64le
-   packages:
-    - Super-Special-Slideshow-for-DVD_medium-on-ppc64le
- - skelcd-openSUSE
- - skelcd-openSUSE-installer
-
-# packages to be put on the medium
-packages:
- - flavors:
-    - DVD medium
-   packages:
-    - DVD-player
-
- - architectures:
-   - i586
-   - i686
-   packages:
-   - kernel-default-pae
-
- - kernel-default
-# take only glibc packages newer than 2.38-9
-# note: this works like a rpm dependency, i.e. the release part is optional
-# and epochs can be specified with EPOCH: prefix
- - glibc > 2.38-9
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/product-composer-0.1/examples/ftp.productcompose 
new/product-composer-0.2/examples/ftp.productcompose
--- old/product-composer-0.1/examples/ftp.productcompose        1970-01-01 
01:00:00.000000000 +0100
+++ new/product-composer-0.2/examples/ftp.productcompose        2023-12-05 
15:36:06.000000000 +0100
@@ -0,0 +1,67 @@
+# Our initial schema version. Be prepared that it breaks until we are
+# in full production mode
+product_compose_schema: 0
+
+vendor: openSUSE
+name: Tumbleweed
+version: 1.0
+
+summary: openSUSE Tumbleweed
+description: >
+  openSUSE Tumbleweed is the rolling distribution by the
+  openSUSE.org project.
+
+
+build_options:
+### For maintenance, otherwise only "the best" version of each package is 
picked:
+ - take_all_available_versions
+### do not abort on missing packages
+ - ignore_missing_packages
+# - hide_flavor_in_product_directory_name
+
+# Enable collection of source and debug packages. Either "include" it
+# on main medium or "split" it away on extra medium.
+source: include
+debug: split
+
+# The default architecture list. Each of these will be put on the medium.
+# It is optional to have a default list, when each flavor defines an
+# architecture list. The main package won't be build in that case.
+architectures: [ x86_64 ]
+
+# A flavor list, each flavor may change the architecture list
+flavors:
+- small
+- large_arm:
+    architectures: [ armv7l, aarch64 ]
+
+# packages to be extracted
+unpack_packages:
+ - flavors:
+    - DVD medium
+   architectures:
+    - ppc64le
+   packages:
+    - Super-Special-Slideshow-for-DVD_medium-on-ppc64le
+ - skelcd-openSUSE
+ - skelcd-openSUSE-installer
+
+# packages to be put on the medium
+packages:
+ - flavors:
+    - DVD medium
+   packages:
+    - DVD-player
+
+ - architectures:
+   - i586
+   - i686
+   packages:
+   - kernel-default-pae
+
+ - kernel-default
+# take only glibc packages newer than 2.38-9
+# note: this works like a rpm dependency, i.e. the release part is optional
+# and epochs can be specified with EPOCH: prefix
+ - glibc > 2.38-9
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/product-composer-0.1/src/productcomposer/cli.py 
new/product-composer-0.2/src/productcomposer/cli.py
--- old/product-composer-0.1/src/productcomposer/cli.py 2023-12-04 
15:22:14.000000000 +0100
+++ new/product-composer-0.2/src/productcomposer/cli.py 2023-12-05 
15:36:06.000000000 +0100
@@ -25,6 +25,8 @@
 local_rpms = {}  # hased via name
 local_updateinfos = {}  # sorted by updateinfo_id
 
+tree_report = {}        # hashed via file name
+
 # hardcoded defaults for now
 chksums_tool = 'sha512sum'
 repomd_checksum_parameter = '--checksum=sha512'
@@ -50,8 +52,9 @@
 
     # Generic options
     for cmd_parser in [verify_parser, build_parser]:
-        cmd_parser.add_argument('-f', '--flavor', default='.x86_64',  
help='Build a given flavor')
+        cmd_parser.add_argument('-f', '--flavor', help='Build a given flavor')
         cmd_parser.add_argument('-v', '--verbose', action='store_true',  
help='Enable verbose output')
+        cmd_parser.add_argument('--reposdir', action='store',  help='Take 
packages from this directory')
         cmd_parser.add_argument('filename', default='default.productcompose',  
help='Filename of product YAML spec')
 
     # build command options
@@ -87,7 +90,7 @@
     raise SystemExit(1)
 
 def warn(msg, details=None):
-    print("WARNING " + msg)
+    print("WARNING: " + msg)
     if details:
         print(details)
 
@@ -96,16 +99,18 @@
 
 
 def build(args):
-    f = args.flavor.split('.')
     flavor = None
-    if f[0] != '':
-        flavor = f[0]
+    if args.flavor:
+        f = args.flavor.split('.')
+        if f[0] != '':
+            flavor = f[0]
 
     yml, archlist = parse_yaml(args.filename, flavor)
     directory = os.getcwd()
     if args.filename.startswith('/'):
         directory = os.path.dirname(args.filename)
-    scan_rpms(directory + "/repos", yml)
+    reposdir = args.reposdir if args.reposdir else directory + "/repos"
+    scan_rpms(reposdir, yml)
 
     if args.clean and os.path.exists(args.out):
         shutil.rmtree(args.out)
@@ -214,6 +219,12 @@
     if not os.path.exists(rpmdir + '/repodata'):
         return
 
+    write_report_file(maindir, maindir + '.report')
+    if sourcedir and maindir != sourcedir:
+        write_report_file(sourcedir, sourcedir + '.report')
+    if debugdir and maindir != debugdir:
+        write_report_file(debugdir, debugdir + '.report')
+
     # CHANGELOG file
     # the tools read the subdirectory of the rpmdir from environment variable
     os.environ['ROOT_ON_CD'] = '.'
@@ -341,13 +352,13 @@
 
 def create_checksums_file(maindir):
     with open(maindir + '/CHECKSUMS', 'a') as chksums_file:
-       for subdir in ('boot', 'EFI', 'docu', 'media.1'):
-           if not os.path.exists(maindir + '/' + subdir):
-               continue
-           for root, dirnames, filenames in os.walk(maindir + '/' + subdir):
-               for name in filenames:
-                   relname = os.path.relpath(root + '/' + name, maindir)
-                   run_helper([chksums_tool, relname], cwd=maindir, 
stdout=chksums_file)
+        for subdir in ('boot', 'EFI', 'docu', 'media.1'):
+            if not os.path.exists(maindir + '/' + subdir):
+                continue
+            for root, dirnames, filenames in os.walk(maindir + '/' + subdir):
+                for name in filenames:
+                    relname = os.path.relpath(root + '/' + name, maindir)
+                    run_helper([chksums_tool, relname], cwd=maindir, 
stdout=chksums_file)
 
 # create a fake entry from an updateinfo package spec
 def create_updateinfo_entry(pkgentry):
@@ -465,7 +476,8 @@
 
     missing_package = False
     for package in create_package_list(yml['unpack_packages'], arch, flavor):
-        rpm = lookup_rpm(arch, package)
+        name, op, epoch, version, release = split_package_spec(package)
+        rpm = lookup_rpm(arch, name, op, epoch, version, release)
         if not rpm:
             warn("package " + package + " not found")
             missing_package = True
@@ -525,12 +537,6 @@
     missing_package = None
     for package in create_package_list(yml['packages'], arch, flavor):
         name, op, epoch, version, release = split_package_spec(package)
-        if name not in local_rpms:
-            warn("package " + package + " not found")
-            missing_package = True
-            continue
-
-        # We may want to put multiple candidates on the medium
         if singlemode:
             rpm = lookup_rpm(arch, name, op, epoch, version, release)
             rpms = [rpm] if rpm else []
@@ -547,7 +553,7 @@
 
             match = re.match(r'^(.*)-([^-]*)-([^-]*)\.([^\.]*)\.rpm$', 
rpm['tags']['sourcerpm'])
             if not match:
-                warn("rpm package " + entry_nvra(rpm) + " does not have a 
source rpm")
+                warn("package " + entry_nvra(rpm) + " does not have a source 
rpm")
                 continue
 
             source_package_name    = match.group(1)
@@ -580,13 +586,46 @@
 def link_file_into_dir(filename, directory):
     if not os.path.exists(directory):
         os.mkdir(directory)
-    outname = directory + '/' + re.sub(r'.*/', '', filename)
+    outname = directory + '/' + os.path.basename(filename)
     if not os.path.exists(outname):
         os.link(filename, outname)
 
 
 def link_entry_into_dir(entry, directory):
     link_file_into_dir(entry['filename'], directory + '/' + 
entry['tags']['arch'])
+    add_entry_to_report(entry, directory)
+
+def add_entry_to_report(entry, directory):
+    outname = directory + '/' + entry['tags']['arch'] + '/' + 
os.path.basename(entry['filename'])
+    # first one wins, see link_file_into_dir
+    if outname not in tree_report:
+        tree_report[outname] = entry
+
+def write_report_file(directory, outfile):
+    root = ET.Element('report')
+    if not directory.endswith('/'):
+        directory += '/'
+    for fn, entry in sorted(tree_report.items()):
+        if not fn.startswith(directory):
+            continue
+        binary = ET.SubElement(root, 'binary')
+        binary.text = 'obs://' + entry['origin']
+        tags = entry['tags']
+        for tag in 'name', 'epoch', 'version', 'release', 'arch', 'buildtime', 
'disturl', 'license':
+            if tags[tag] is None or tags[tag] == '':
+                continue
+            if tag == 'epoch' and tags[tag] == 0:
+                continue
+            if tag == 'arch':
+                binary.set('binaryarch', str(tags[tag]))
+            else:
+                binary.set(tag, str(tags[tag]))
+        if tags['name'].endswith('-release'):
+            cpeid = read_cpeid(entry['filename'])
+            if cpeid:
+                binary.set('cpeid', cpeid)
+    tree = ET.ElementTree(root)
+    tree.write(outfile)
 
 def entry_qualifies(entry, arch, name, op, epoch, version, release):
     tags = entry['tags']
@@ -651,17 +690,12 @@
     ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
 
     for dirpath, dirs, files in os.walk(directory):
-        subdirs = dirpath.replace(directory,'').split('/')
-        if len(subdirs) < 4:
+        reldirpath = os.path.relpath(dirpath, directory)
+        subdirs = reldirpath.split('/')
+        if len(subdirs) < 1:
             continue
-        project = subdirs[-3]
-        repository = subdirs[-2]
         arch = subdirs[-1]
-  # we try to avoid second path config for now
-  #      if not project+"/"+repository in yml['repositories']:
-  #          print("Warning: local repo not listed in yml file: " + project + 
"/" + repository)
-  #          continue
-        note("scanning: " + project + "/" + repository)
+        note("scanning: " + reldirpath)
         for filename in files:
             fname = os.path.join(dirpath, filename)
             if arch == 'updateinfo':
@@ -672,13 +706,13 @@
                 h = ts.hdrFromFdno(fd)
                 os.close(fd)
                 tags = {}
-                for tag in 'name', 'epoch', 'version', 'release', 'arch', 
'sourcerpm', 'nosource', 'nopatch':
+                for tag in 'name', 'epoch', 'version', 'release', 'arch', 
'sourcerpm', 'nosource', 'nopatch', 'buildtime', 'disturl', 'license':
                     tags[tag] = h[tag]
 
                 if not tags['sourcerpm']:
                     tags['arch'] = 'nosrc' if tags['nosource'] or 
tags['nopatch'] else 'src'
 
-                item = { 'filename': fname, 'tags': tags }
+                item = { 'filename': fname, 'origin':os.path.join(reldirpath, 
filename), 'tags': tags }
 
                 # add entry to local_rpms hash
                 name = tags['name']
@@ -686,6 +720,35 @@
                     local_rpms[name] = []
                 local_rpms[name].append(item)
 
+def cpeid_hexdecode(p):
+    pout = ''
+    while True:
+        match = re.match(r'^(.*?)%([0-9a-fA-F][0-9a-fA-F])(.*)', p)
+        if not match:
+            return pout + p
+        pout = pout + match.group(1) + chr(int(match.group(2), 16))
+        p = match.group(3)
+
+def read_cpeid(fname):
+    ts = rpm.TransactionSet()
+    ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES)
+    fd = os.open(fname, os.O_RDONLY)
+    h = ts.hdrFromFdno(fd)
+    os.close(fd)
+    pn = h['providename']
+    pf = h['provideflags']
+    pv = h['provideversion']
+    if pn and pf and pv:
+        idx = 0
+        for p in h['providename']:
+            if p == 'product-cpeid()':
+                f = pf[idx]
+                v = pv[idx]
+                if v and f and (f & 14) == 8:
+                    return cpeid_hexdecode(v)
+            idx = idx + 1
+    return None
+
 if __name__ == "__main__":
     try:
         status = main()

++++++ product-composer.obsinfo ++++++
--- /var/tmp/diff_new_pack.ucyY1r/_old  2023-12-06 23:47:29.189625291 +0100
+++ /var/tmp/diff_new_pack.ucyY1r/_new  2023-12-06 23:47:29.189625291 +0100
@@ -1,5 +1,5 @@
 name: product-composer
-version: 0.1
-mtime: 1701699734
-commit: 911f9cad2d0557836155b12b68df6c78b1c489bd
+version: 0.2
+mtime: 1701786966
+commit: 6657c85d63ff68142000d775a5bf65bc2bc32bda
 

Reply via email to