def __init__(self, filename): # # Workaround for https://github.com/rpm-software-management/rpm/pull/1067 # See also http://lists.rpm.org/pipermail/rpm-list/2020-February/002012.html # rpm.reloadConfig() self._spec = rpm.spec(filename) self._filename = filename
def get_rpm_spec(cls, path: str, sourcedir: str, predefined_macros: Dict[str, str]) -> rpm.spec: # reset all macros and settings rpm.reloadConfig() # ensure that %{_sourcedir} macro is set to proper location MacroHelper.purge_macro('_sourcedir') rpm.addMacro('_sourcedir', sourcedir) # add predefined macros for macro, value in predefined_macros.items(): rpm.addMacro(macro, value) try: spec = cls.parse_spec(path, flags=rpm.RPMSPEC_ANYARCH) except RebaseHelperError: # try again with RPMSPEC_FORCE flag (the default) spec = cls.parse_spec(path) return spec
def get_package_name(spec_path): """ Obtain name of a package described by spec at spec_path. :param str spec_path: path to a spec file :returns str: package name :raises PackageNameCouldNotBeObtainedException """ ts = rpm.ts() try: rpm_spec = ts.parseSpec(spec_path) except ValueError as e: log.debug("Could not parse {0} with error {1}. Trying manual parsing." .format(spec_path, str(e))) with open(spec_path, 'r') as spec_file: spec_lines = spec_file.readlines() patterns = [ re.compile(r'^(name):\s*(\S*)$', re.IGNORECASE), re.compile(r'^%global\s*(\S*)\s*(\S*)$'), re.compile(r'^%define\s*(\S*)\s*(\S*)$')] for spec_line in spec_lines: for pattern in patterns: match = pattern.match(spec_line) if not match: continue rpm.addMacro( match.group(1), match.group(2)) package_name = rpm.expandMacro("%{name}") rpm.reloadConfig() if not re.match(r'[a-zA-Z0-9-._+]+', package_name): raise PackageNameCouldNotBeObtainedException( "Got invalid package package name '{0}' from {1}.".format(package_name, spec_path)) return package_name
def parse_spec(spec_file, keep_config=False): """Simple wrapper around rpm.spec that catches errors printed to stdout :param spec_file: spec file name :param keep_config: If set to True, does not call rpm.reloadConfig() This can be used to preserve the internal rpm state with any custom macros or definitions. :returns: rpm.spec object instance :raises: ValueError in case parsing failed """ if not keep_config: rpm.reloadConfig() with NamedTemporaryFile(mode="w+") as tmplog: # rpm will print errors to stdout if logfile is not set rpm.setLogFile(tmplog) try: spec = rpm.spec(spec_file) except ValueError as exc: # re-raise errors with rpm output appended to message raise ValueError(str(exc) + open(tmplog.name, 'r').read()) return spec
error = False for define in opts.define: words = define.split(None, 1) if len(words) == 1: self.logger.error('Error: No EXPR given for MACRO %%%s' % words[0]) error = True continue macros.append(words) if error: sys.exit(1) for name in specnames: # (re)load rpm config for target if set if reloadworks and opts.target: rpm.reloadConfig(opts.target) for macro in macros: rpm.addMacro(*macro) try: spec = rpm.spec(name) except ValueError: self.logger.error("Bad spec: %s" % name) continue # reset default rpm config after each parse to avoid side-effects if reloadworks: rpm.reloadConfig() buildreqs = []
def parse_spec(spec): rpm.reloadConfig() with tempfile.NamedTemporaryFile(suffix='.spec') as tmpfile: tmpfile.write(spec) tmpfile.flush() return rpm.spec(tmpfile.name)