def parse_package_list_str(pkg_list_raw, default_version=None): ''' Parse a "Package-List" field and return its information in PackageInfo data structures. See https://www.debian.org/doc/debian-policy/ch-controlfields.html#package-list ''' res = [] for line in pkg_list_raw.split('\n'): parts = split_strip(line, ' ') if len(parts) < 4: continue pi = PackageInfo() pi.name = parts[0] pi.version = default_version pi.deb_type = debtype_from_string(parts[1]) pi.section = parts[2] pi.priority = packagepriority_from_string(parts[3]) if len(parts) > 4: # we have additional data raw_vals = split_strip(parts[4], ' ') for v in raw_vals: if v.startswith('arch='): # handle architectures pi.architectures = v[5:].split(',') res.append(pi) return res
def parse_checksums_list(data, base_dir=None): files = [] if not data: return files for line in data.split('\n'): parts = split_strip(line, ' ') # f43923ace1c558ad9f9fa88eb3f1764a8c0379013aafbc682a35769449fe8955 2455 0ad_0.0.20-1.dsc if len(parts) != 3: continue af = ArchiveFile() af.sha256sum = parts[0] af.size = int(parts[1]) if not base_dir: af.fname = parts[2] else: af.fname = os.path.join(base_dir, parts[2]) files.append(af) return files
def _read_binary_packages_from_tf(self, tf, tf_fname, suite, component, arch, deb_type): requested_arch_is_all = arch.name == 'all' pkgs = [] for e in tf: pkgname = e['Package'] pkgversion = e['Version'] if not pkgname or not pkgversion: raise Exception('Found invalid block (no Package and Version fields) in Packages file "{}".'.format(tf_fname)) break arch_name = e['Architecture'] # we deal with arch:all packages separately if not requested_arch_is_all and arch_name == 'all': continue # sanity check if arch_name != arch.name: log.warning('Found package "{}::{}/{}" with unexpeced architecture "{}" (expected "{}")'.format(self._name, pkgname, pkgversion, arch_name, arch.name)) pkg = BinaryPackage() pkg.repo = self._repo_entity pkg.name = pkgname pkg.component = component pkg.version = pkgversion if suite not in pkg.suites: pkg.suites.append(suite) pkg.architecture = arch pkg.maintainer = e['Maintainer'] source_id = e.get('Source') if not source_id: pkg.source_name = pkg.name pkg.source_version = pkg.version elif '(' in source_id: pkg.source_name = source_id[0:source_id.index('(') - 1].strip() pkg.source_version = source_id[source_id.index('(') + 1:source_id.index(')')].strip() else: pkg.source_name = source_id pkg.source_version = pkg.version pkg.size_installed = int(e.get('Installed-Size', '0')) pkg.depends = split_strip(e.get('Depends', ''), ',') pkg.pre_depends = split_strip(e.get('Pre-Depends', ''), ',') pkg.homepage = e.get('Homepage') pkg.section = e['Section'] pkg.description = e['Description'] pkg.description_md5 = e.get('Description-md5') pkg.priority = packagepriority_from_string(e['Priority']) pkg.bin_file = ArchiveFile() pkg.bin_file.fname = e['Filename'] pkg.bin_file.size = int(e.get('Size', '0')) pkg.bin_file.sha256sum = e['SHA256'] pkg.deb_type = DebType.DEB if pkg.bin_file.fname.endswith('.udeb'): pkg.deb_type = DebType.UDEB # do some issue-reporting if not pkg.bin_file.fname: log.warning('Binary package "{}/{}/{}" seems to have no files.'.format(pkg.name, pkg.version, arch.name)) # update UUID and add package to results set pkg.update_uuid() pkgs.append(pkg) return pkgs
def source_packages(self, suite, component): ''' Return a list of all source packages in the given suite and component. ''' assert type(suite) is ArchiveSuite assert type(component) is ArchiveComponent index_fname = self.index_file(suite.name, os.path.join(component.name, 'source', 'Sources.xz')) if not index_fname: return [] pkgs = [] with TagFile(index_fname) as tf: for e in tf: pkgname = e['Package'] pkgversion = e['Version'] if not pkgname or not pkgversion: raise Exception('Found invalid block (no Package and Version fields) in Sources file "{}".'.format(index_fname)) break pkg = SourcePackage() pkg.repo = self._repo_entity pkg.name = pkgname pkg.component = component if suite not in pkg.suites: pkg.suites.append(suite) pkg.version = pkgversion pkg.architectures = split_strip(e['Architecture'], ' ') pkg.standards_version = e.get('Standards-Version', '0~notset') pkg.format_version = e['Format'] pkg.vcs_browser = e.get('Vcs-Browser') pkg.homepage = e.get('Homepage') pkg.maintainer = e['Maintainer'] pkg.uploaders = split_strip(e.get('Uploaders', ''), ',') # FIXME: Careful! Splitting just by comma isn't enough! We need to parse this properly. pkg.build_depends = split_strip(e.get('Build-Depends', ''), ',') pkg.directory = e['Directory'] pkg.files = parse_checksums_list(e.get('Checksums-Sha256'), pkg.directory) binaries = [] raw_pkg_list = e.get('Package-List', None) if not raw_pkg_list: for bpname in e.get('Binary', '').split(','): if not bpname: continue bpname = bpname.strip() pi = PackageInfo() pi.deb_type = DebType.DEB pi.name = bpname pi.ver = pkg.version binaries.append(pi) else: binaries = parse_package_list_str(raw_pkg_list, pkg.version) pkg.binaries = binaries # do some issue-reporting if not pkg.files and pkg.format_version != '1.0': log.warning('Source package {}/{} seems to have no files (in {}).'.format(pkg.name, pkg.version, self.location)) # add package to results set pkg.update_uuid() pkgs.append(pkg) return pkgs