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 2024-03-07 18:31:54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/product-composer (Old) and /work/SRC/openSUSE:Factory/.product-composer.new.1770 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "product-composer" Thu Mar 7 18:31:54 2024 rev:7 rq:1156038 version:0.4.1 Changes: -------- --- /work/SRC/openSUSE:Factory/product-composer/product-composer.changes 2024-03-06 23:07:16.159272864 +0100 +++ /work/SRC/openSUSE:Factory/.product-composer.new.1770/product-composer.changes 2024-03-07 18:32:55.632786828 +0100 @@ -1,0 +2,6 @@ +Thu Mar 7 15:49:18 UTC 2024 - Adrian Schröter <adr...@suse.de> + +- update to version 0.4.1 + * write translations of package descriptions + +------------------------------------------------------------------- Old: ---- product-composer-0.4.0.obscpio New: ---- product-composer-0.4.1.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ product-composer.spec ++++++ --- /var/tmp/diff_new_pack.8zKkwt/_old 2024-03-07 18:32:56.516819448 +0100 +++ /var/tmp/diff_new_pack.8zKkwt/_new 2024-03-07 18:32:56.520819596 +0100 @@ -17,7 +17,7 @@ Name: product-composer -Version: 0.4.0 +Version: 0.4.1 Release: 0 Summary: Product Composer License: GPL-2.0-or-later ++++++ _service ++++++ --- /var/tmp/diff_new_pack.8zKkwt/_old 2024-03-07 18:32:56.596822400 +0100 +++ /var/tmp/diff_new_pack.8zKkwt/_new 2024-03-07 18:32:56.612822991 +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.4.0</param> - <param name="revision">0.4.0</param> + <param name="version">0.4.1</param> + <param name="revision">0.4.1</param> </service> <service name="set_version" mode="manual" /> <service name="tar" mode="buildtime" /> ++++++ product-composer-0.4.0.obscpio -> product-composer-0.4.1.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/product-composer-0.4.0/examples/ftp.productcompose new/product-composer-0.4.1/examples/ftp.productcompose --- old/product-composer-0.4.0/examples/ftp.productcompose 2024-03-06 16:07:52.000000000 +0100 +++ new/product-composer-0.4.1/examples/ftp.productcompose 2024-03-07 16:46:38.000000000 +0100 @@ -67,7 +67,6 @@ - kernel-default-pae - packages: - supportstatus: l2 - 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 @@ -75,3 +74,4 @@ - glibc > 2.38-9 add: - 32bit + supportstatus: l2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/product-composer-0.4.0/src/productcomposer/cli.py new/product-composer-0.4.1/src/productcomposer/cli.py --- old/product-composer-0.4.0/src/productcomposer/cli.py 2024-03-06 16:07:52.000000000 +0100 +++ new/product-composer-0.4.1/src/productcomposer/cli.py 2024-03-07 16:46:38.000000000 +0100 @@ -34,6 +34,8 @@ # global db for supportstatus supportstatus = {} +# per package override via supportstatus.txt file +supportstatus_override = {} def main(argv=None) -> int: """ Execute the application CLI. @@ -113,11 +115,16 @@ die(None) yml = parse_yaml(args.filename, flavor) + directory = os.getcwd() if args.filename.startswith('/'): directory = os.path.dirname(args.filename) reposdir = args.reposdir if args.reposdir else directory + "/repos" + supportstatus_fn = os.path.join(directory,'supportstatus.txt') + if os.path.isfile(supportstatus_fn): + parse_supportstatus(supportstatus_fn) + pool = Pool() note(f"scanning: {reposdir}") pool.scan(reposdir) @@ -143,11 +150,11 @@ if yml['product_compose_schema'] != 0 and yml['product_compose_schema'] != 0.1: die(f"Unsupported product composer schema: {yml['product_compose_schema']}") - if yml['flavors'] is None: + if 'flavors' not in yml: yml['flavors'] = [] if flavor: - if 'flavors' not in yml or flavor not in yml['flavors']: + if flavor not in yml['flavors']: die("Flavor not found: " + flavor) f = yml['flavors'][flavor] # overwrite global values from flavor overwrites @@ -160,14 +167,20 @@ if 'version' in f: yml['version'] = f['version'] - if not 'architectures' in yml: # and yml['architectures'] is None: + if 'architectures' not in yml or not yml['architectures']: die("No architecture defined. Maybe wrong flavor?") - if yml['build_options'] is None: + if 'build_options' not in yml: yml['build_options'] = [] return yml +def parse_supportstatus(filename): + with open(filename, 'r') as file: + for line in file.readlines(): + a = line.strip().split(' ') + supportstatus_override[a[0]] = a[1] + def get_product_dir(yml, flavor, release): name = yml['name'] + "-" + str(yml['version']) if 'product_directory_name' in yml: @@ -434,53 +447,96 @@ # Create the main susedata.xml with support and disk usage informations def create_susedata_xml(rpmdir, yml): + # get supported translations based on local packages + i18ndir = '/usr/share/locale/en_US/LC_MESSAGES/' + p = re.compile('package-translations-(.+).mo') + languages = [] + i18ndata = {} + i18ndata_count = {} + i18ntrans = {} + import gettext + for file in os.listdir(i18ndir): + m = p.match(file) + if m: + lang = m.group(1) + languages.append(lang) + i18ntrans[lang] = gettext.translation(f'package-translations-{lang}', + languages=['en_US']) + # read repomd.xml ns='{http://linux.duke.edu/metadata/repo}' tree = ET.parse(rpmdir + '/repodata/repomd.xml') - root = tree.getroot() - for p in root.findall(f".//{ns}data[@type='primary']/{ns}location"): - primary_fn = p.attrib['href'] + primary_fn = tree.find(f".//{ns}data[@type='primary']/{ns}location").attrib['href'] - # read primary.xml - content = None + # read compressed primary.xml + openfunction = None if primary_fn.endswith('.gz'): - import gzip - content = gzip.open(primary_fn, 'r').read() + import gzip + openfunction = gzip.open elif primary_fn.endswith('.zst'): - import zstandard - content = zstandard.open(rpmdir + '/' + primary_fn, 'rb').read() - root = ET.fromstring(content) + import zstandard + openfunction = zstandard.open + else: + die(f"unsupported primary compression type ({primary_fm})") + tree = ET.parse(openfunction(rpmdir + '/' + primary_fn, 'rb')) ns='{http://linux.duke.edu/metadata/common}' # Create susedata structure susedata = ET.Element('susedata') susedata.set('xmlns', 'http://linux.duke.edu/metadata/susedata') # go for every rpm file of the repo via the primary - count=0 - for pkg in root.findall(f".//{ns}package[@type='rpm']"): - name = pkg.find(f'{ns}name').text + count = 0 + for pkg in tree.findall(f".//{ns}package[@type='rpm']"): + name = pkg.find(f'{ns}name').text + pkgid = pkg.find(f'{ns}checksum').text + arch = pkg.find(f'{ns}arch').text + version = pkg.find(f'{ns}version').attrib + package = ET.SubElement(susedata, 'package') package.set('name', name) - package.set('pkgid', pkg.find(f'{ns}checksum').text) - package.set('arch', pkg.find(f'{ns}arch').text) - ET.SubElement(package, 'version', pkg.find(f'{ns}version').attrib) - count=count + 1 - - supportlevel = None + package.set('pkgid', pkgid) + package.set('arch', arch) + ET.SubElement(package, 'version', version) if name in supportstatus and supportstatus[name] is not None: - supportlevel = supportstatus[name] - elif 'default_supportstatus' in yml: - supportlevel = yml['default_supportstatus'] - if supportlevel: - ET.SubElement(package, 'keyword').text = f'support_{supportlevel}' + ET.SubElement(package, 'keyword').text = f'support_{supportstatus[name]}' + count += 1 + # look for pattern category + category = None + for c in pkg.findall(".//{http://linux.duke.edu/metadata/rpm}entry[@name='pattern-category()']"): + category = Package._cpeid_hexdecode(c.get('ver')) + + # looking for translations for this package + summary = pkg.find(f'{ns}summary').text + description = pkg.find(f'{ns}description').text + for lang in languages: + isummary = i18ntrans[lang].gettext(summary) + idescription = i18ntrans[lang].gettext(description) + icategory = i18ntrans[lang].gettext(category) if category else None + if isummary == summary and idescription == description: + continue + if lang not in i18ndata: + i18ndata[lang] = ET.Element('susedata') + i18ndata[lang].set('xmlns', 'http://linux.duke.edu/metadata/susedata') + i18ndata_count[lang] = 0 + i18ndata_count[lang] += 1 + ipackage = ET.SubElement(i18ndata[lang], 'package') + ipackage.set('name', name) + ipackage.set('pkgid', pkgid) + ipackage.set('arch', arch) + ET.SubElement(ipackage, 'version', version) + if isummary != summary: + ET.SubElement(ipackage, 'summary', {'lang': lang}).text = isummary + if idescription != description: + ET.SubElement(ipackage, 'description', {'lang': lang}).text = idescription + if icategory != category: + ET.SubElement(ipackage, 'category', {'lang': lang}).text = icategory susedata.set('packages', str(count)) - susedata_fn=rpmdir + '/susedata.xml' - sd_file = open(susedata_fn, 'x') ET.indent(susedata, space=" ", level=0) - sd_file.write(ET.tostring(susedata, encoding='utf8', method='xml').decode()) - sd_file.close() + susedata_fn = rpmdir + '/susedata.xml' + with open(susedata_fn, 'x') as sd_file: + sd_file.write(ET.tostring(susedata, encoding=ET_ENCODING)) mr = ModifyrepoWrapper( file=susedata_fn, directory=os.path.join(rpmdir, "repodata"), @@ -488,6 +544,22 @@ mr.run_cmd() os.unlink(susedata_fn) + for lang in i18ndata: + i18ndata[lang].set('packages', str(i18ndata_count[lang])) + susedata_fn=rpmdir + f'/susedata.{lang}.xml' + ET.indent(i18ndata[lang], space=" ", level=0) + + with open(susedata_fn, 'x') as sd_file: + sd_file.write(ET.tostring(i18ndata[lang], encoding=ET_ENCODING)) + mr = ModifyrepoWrapper( + file=susedata_fn, + mdtype=f'susedata.{lang}', + directory=os.path.join(rpmdir, "repodata"), + ) + mr.run_cmd() + os.unlink(susedata_fn) + + # Add updateinfo.xml to metadata def process_updateinfos(rpmdir, yml, pool, flavor, debugdir, sourcedir): if not pool.updateinfos: @@ -702,7 +774,10 @@ for rpm in rpms: link_entry_into_dir(rpm, rpmdir) - supportstatus[rpm.name] = sel.supportstatus + if rpm.name in supportstatus_override: + supportstatus[rpm.name] = supportstatus_override[rpm.name] + else: + supportstatus[rpm.name] = sel.supportstatus srcrpm = rpm.get_src_package() if not srcrpm: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/product-composer-0.4.0/src/productcomposer/core/Package.py new/product-composer-0.4.1/src/productcomposer/core/Package.py --- old/product-composer-0.4.0/src/productcomposer/core/Package.py 2024-03-06 16:07:52.000000000 +0100 +++ new/product-composer-0.4.1/src/productcomposer/core/Package.py 2024-03-07 16:46:38.000000000 +0100 @@ -13,7 +13,9 @@ return self.location = location h = self._read_rpm_header(rpm_ts=rpm_ts) - for tag in 'name', 'epoch', 'version', 'release', 'arch', 'sourcerpm', 'buildtime', 'disturl', 'license': + for tag in 'name', 'epoch', 'version', 'release', 'arch', 'sourcerpm', \ + 'buildtime', 'disturl', 'license', 'filesizes', 'filemodes', \ + 'filedevices', 'fileinodes', 'dirindexes', 'basenames', 'dirnames': val = h[tag] if isinstance(val, bytes): val = val.decode('utf-8') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/product-composer-0.4.0/src/productcomposer/core/PkgSelect.py new/product-composer-0.4.1/src/productcomposer/core/PkgSelect.py --- old/product-composer-0.4.0/src/productcomposer/core/PkgSelect.py 2024-03-06 16:07:52.000000000 +0100 +++ new/product-composer-0.4.1/src/productcomposer/core/PkgSelect.py 2024-03-07 16:46:38.000000000 +0100 @@ -131,6 +131,7 @@ out.epoch = self.epoch out.version = self.version out.release = self.release + out.supportstatus = self.supportstatus return out def __str__(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/product-composer-0.4.0/src/productcomposer/core/PkgSet.py new/product-composer-0.4.1/src/productcomposer/core/PkgSet.py --- old/product-composer-0.4.0/src/productcomposer/core/PkgSet.py 2024-03-06 16:07:52.000000000 +0100 +++ new/product-composer-0.4.1/src/productcomposer/core/PkgSet.py 2024-03-07 16:46:38.000000000 +0100 @@ -30,6 +30,9 @@ s1 = set(self) for sel in other.pkgs: if sel not in s1: + if self.supportstatus is not None and sel.supportstatus is None: + sel = sel.copy() + sel.supportstatus = self.supportstatus self.pkgs.append(sel) s1.add(sel) self.byname = None ++++++ product-composer.obsinfo ++++++ --- /var/tmp/diff_new_pack.8zKkwt/_old 2024-03-07 18:32:57.036838638 +0100 +++ /var/tmp/diff_new_pack.8zKkwt/_new 2024-03-07 18:32:57.056839376 +0100 @@ -1,5 +1,5 @@ name: product-composer -version: 0.4.0 -mtime: 1709737672 -commit: 516f1f24af42b5bfa5a7e751585c678d002a43f5 +version: 0.4.1 +mtime: 1709826398 +commit: d4343d718c9ebcc9bcdce68b133b0c84979c870e