Welcome to rebase-helper

Code Health GitLab CI build status Travis CI build status Documentation build status

There are several steps that need to be done when rebasing a package. The goal of rebase-helper is to automate most of these steps.

How to get it running?

rebase-helper is packaged in Fedora, so you can just install it with dnf.

If you wish to use the latest codebase, consult installation instructions.

How to use it?

After installation, execute rebase-helper from a directory containing SPEC file, sources and patches (usually cloned dist-git repository).

Without any arguments or configuration rebase-helper will attempt to determine the latest upstream version automatically. If that fails, or if you wish to rebase to some different version, you can specify it explicitly as an argument:

$ rebase-helper 3.1.10

or you can pass source tarball filename instead:

$ rebase-helper foo-4.2.tar.gz

For complete CLI reference see usage.

Alternatively, you can run rebase-helper in a container:

$ docker run -it -e PACKAGE=foo rebasehelper/rebase-helper:latest

See docker reference for more information.

How does it work?

The following steps describe a rebase process:

  • rebase-helper-workspace and rebase-helper-results directories are created
  • original SPEC file is copied to rebase-helper-results/rebased-sources directory and its Version tag is modified
  • old and new source tarballs are downloaded and extracted to rebase-helper-workspace directory
  • downstream patches are rebased on top of new sources using git-rebase, resulting modified patches are saved to rebase-helper-results/rebased-sources directory
  • old and new source RPMs are created and built with selected build tool
  • multiple checker tools are run against both sets of packages and their output is stored in rebase-helper-results/checkers directory
  • rebase-helper-workspace directory is removed

Rebasing of downstream patches is done as follows:

  • new git repository is initialized and the old sources are extracted and commited
  • each downstream patch is applied and changes introduced by it are commited
  • new sources are extracted and added as a remote repository
  • git-rebase is used to rebase the commits on top of new sources
  • original patches are modified/deleted accordingly
  • resulting files are stored in rebase-helper-results/rebased-sources
  • diff against original files is saved to rebase-helper-results/changes.patch

User Guide

Installation

rebase-helper is packaged in Fedora, so you can just install it with dnf.

If you can’t or don’t want to use rebase-helper package, you have to install, apart from Python requirements listed in get_requirements function in setup.py, the following dependencies:

Dependency Package name (in Fedora) Notes
git git for rebasing of downstream patches
rpmbuild rpm-build for building SRPM and for rpmbuild build tool
mock mock for mock build tool, optional
koji koji for koji build tool, optional
rpmdiff rpmlint for rpmdiff checker, optional
abipkgdiff libabigail for abipkgdiff checker, optional
pkgdiff pkgdiff for pkgdiff checker, optional
csmock csmock for csmock checker, optional

Rebasing in container

rebase-helper can be run in Docker container. The package to be rebased has to be specified in PACKAGE environment variable. Alternatively, you can set REPOSITORY environment variable and point it to URL of any dist-git repository. In both cases, you can reference a specific branch, tag or commit by appending it to the package name or the repository URL:

$ docker run -it -e PACKAGE=foo#branch=f26 rebasehelper/rebase-helper:latest --outputtool json

Results of the rebase will be stored in an exported volume.

Usage

DESCRIPTION

rebase-helper is a tool which helps package maintainers to rebase their packages to latest upstream versions.

It should be executed from a directory containing spec file, sources and patches (usually cloned dist-git repository).

The new version is specified by SOURCES argument, which can be either version number or filename of the new source archive. Starting with version 0.10.0, this argument can be omitted and the new version determined automatically using one of available versioneers.

OPTIONS
Positional arguments
SOURCES
version number or filename of the new source archive
Optional arguments
-h, --help
show help message and exit
--version
show rebase-helper version and exit
-v, --verbose
be more verbose
--color {always,never,auto}
colorize the output, defaults to auto
--results-dir RESULTS_DIR
directory where rebase-helper output will be stored
-p, --patch-only
only apply patches
-b, --build-only
only build SRPMs and RPMs
--comparepkgs-only COMPAREPKGS_DIR
compare already built packages, COMPAREPKGS_DIR must be a directory with the following structure: <dir_name>/{old,new}/RPM
-c, --continue
continue previously interrupted rebase
--buildtool {copr,rpmbuild,mock}
build tool to use, defaults to mock
--srpm-buildtool {rpmbuild,mock}
SRPM build tool to use, defaults to rpmbuild
--pkgcomparetool {rpmdiff,abipkgdiff,pkgdiff,csmock}
set of tools to use for package comparison, defaults to rpmdiff,abipkgdiff,pkgdiff
--outputtool {text,json}
tool to use for formatting rebase output, defaults to text
--versioneer {cpan,pypi,rubygems,anitya,npmjs}
tool to use for determining latest upstream version
--versioneer-blacklist {cpan,pypi,rubygems,anitya,npmjs}
prevent specified versioneers from being run
--spec-hook-blacklist {RubyHelperHook,PyPIURLFixHook,TypoFixHook}
prevent specified spec hooks from being run
--non-interactive
do not interact with user
--not-download-sources
do not download sources
-w, --keep-workspace
do not remove workspace directory after finishing
--disable-inapplicable-patches
disable inapplicable patches in rebased SPEC file
--get-old-build-from-koji
do not build old sources, download latest build from Koji instead
--skip-version-check
force rebase even if current version is newer than requested version
--builds-nowait
do not wait for remote builds to finish
--build-tasks OLD_TASK,NEW_TASK
comma-separated remote build task ids
--builder-options BUILDER_OPTIONS
enable arbitrary local builder option(s), enclose BUILDER_OPTIONS in quotes to pass more than one
--srpm-builder-options SRPM_BUILDER_OPTIONS
enable arbitrary local srpm builder option(s), enclose SRPM_BUILDER_OPTIONS in quotes to pass more than one
--changelog-entry CHANGELOG_ENTRY
text to use as changelog entry, can contain RPM macros, which will be expanded
--config-file CONFIG_FILE
path to a configuration file, defaults to $XDG_CONFIG_HOME/rebase-helper.cfg

Writing plugins

Starting with version 0.10.0, rebase-helper is extensible through plugins.

You can implement your own build tool, checker, output tool, SPEC hook or versioneer. All you have to do is to derive your plugin from corresponding base class, implement all necessary methods and register it using one of the following entry points:

Plugin type Entry point Base class
build tool rebasehelper.build_tools rebasehelper.build_helper.BuildToolBase
checker rebasehelper.checkers rebasehelper.checker.BaseChecker
output tool rebasehelper.output_tools rebasehelper.output_tool.BaseOutputTool
SPEC hook rebasehelper.spec_hooks rebasehelper.specfile.BaseSpecHook
versioneer rebasehelper.versioneers rebasehelper.versioneer.BaseVersioneer
Example
my_spec_hook/__init__.py
from rebasehelper.specfile import BaseSpecHook


class MySpecHook(BaseSpecHook):

    NAME = 'MySpecHook'

    @classmethod
    def get_name(cls):
        return cls.NAME

    @classmethod
    def run(cls, spec_file, rebase_spec_file):
        """
        This method is called after original SPEC file is processed

        :param spec_file: SpecFile object representing original SPEC file
        :param rebase_spec_file: SpecFile object representing rebased SPEC file
        """
        rebase_spec_file.spec_content.insert(0, '# processed by %s\n' % cls.NAME)
        rebase_spec_file.save()
setup.py
from setuptools import setup


setup(
    name='MySpecHook',
    version='0.1',
    description='Custom SPEC hook for rebase-helper',
    author='John Doe',
    install_requires=['rebasehelper>=0.10.0'],
    packages=['my_spec_hook'],
    entry_points={
        'rebasehelper.spec_hooks': ['my_spec_hook = my_spec_hook:MySpecHook']
    }
)

API

Application module

class rebasehelper.application.Application(cli_conf, execution_dir, results_dir, debug_log_file)[source]
build_packages()[source]

Function calls build class for building packages

debug_log_file = None
static extract_archive(archive_path, destination)[source]

Extracts given archive into the destination and handle all exceptions.

Parameters:
  • archive_path – path to the archive to be extracted
  • destination – path to a destination, where the archive should be extracted to
Returns:

static extract_sources(archive_path, destination)[source]

Function extracts a given Archive and returns a full dirname to sources

generate_patch()[source]

Generates patch to the results_dir containing all needed changes for the rebased package version

get_all_log_files()[source]

Function returns all log_files created by rebase-helper First if debug log file and second is report summary log file

Returns:
get_checker_outputs()[source]
get_new_build_logs()[source]
get_rebased_patches()[source]

Function returns a list of patches either ‘’: [list_of_deleted_patches] :return:

get_rebasehelper_data()[source]
get_rpm_packages(dirname)[source]

Function returns RPM packages stored in dirname/old and dirname/new directories

Parameters:dirname – directory where are stored old and new RPMS
Returns:
kwargs = {}
new_rest_sources = []
new_sources = ''
old_rest_sources = []
old_sources = ''
patch_sources(sources)[source]
prepare_sources()[source]

Function prepares a sources.

Returns:
print_summary(exception=None)[source]

Save rebase-helper result and print the summary using output_tools_runner :param exception: Error message from rebase-helper :return:

print_task_info(builder)[source]
rebase_spec_file = None
rebase_spec_file_path = None
rebased_patches = {}
rebased_repo = None
report_log_file = None
result_file = ''
run()[source]
run_download_compare(tasks_dict, dir_name)[source]
run_package_checkers(results_dir)[source]

Runs checkers on packages and stores results in a given directory.

Parameters:results_dir (str) – Path to directory in which to store the results.
Returns:None
set_upstream_monitoring()[source]
static setup(cli_conf)[source]
spec_file = None
spec_file_path = None
temp_dir = ''
upstream_monitoring = False

Archive module

class rebasehelper.archive.Archive(filename=None)[source]

Class representing an archive with sources

extract_archive(path=None)[source]

Extracts the archive into the given path

Parameters:path – Path where to extract the archive to.
Returns:
classmethod get_supported_archives()[source]

Return list of supported archive types

class rebasehelper.archive.ArchiveTypeBase[source]

Base class for various archive types

EXTENSION = ''
classmethod extract(filename=None, *args, **kwargs)[source]

Extracts the archive into the given path

Parameters:path – Path where to extract the archive to.
Returns:
classmethod match(filename=None, *args, **kwargs)[source]

Checks if the filename matches the archive type. If yes, returns True, otherwise returns False.

classmethod open(filename=None, *args, **kwargs)[source]

Opens archive with the given filename and returns the proper archive type object.

class rebasehelper.archive.Bz2ArchiveType[source]

.bz2 archive type

EXTENSION = '.bz2'
classmethod extract(archive=None, filename=None, path=None, *args, **kwargs)[source]
classmethod open(filename=None)[source]
class rebasehelper.archive.GemPseudoArchiveType[source]

.gem files are not archives - this is a pseudo type

EXTENSION = '.gem'
classmethod extract(archive=None, filename=None, path=None, *args, **kwargs)[source]
classmethod open(filename=None)[source]
class rebasehelper.archive.TarBz2ArchiveType[source]

.tar.bz2 archive type

EXTENSION = '.tar.bz2'
class rebasehelper.archive.TarGzArchiveType[source]

.tar.gz archive type

EXTENSION = '.tar.gz'
classmethod extract(archive=None, filename=None, path=None, *args, **kwargs)[source]
classmethod open(filename=None)[source]
class rebasehelper.archive.TarXzArchiveType[source]

.tar.xz archive type

EXTENSION = '.tar.xz'
classmethod extract(archive=None, filename=None, path=None, *args, **kwargs)[source]
classmethod open(filename=None)[source]
class rebasehelper.archive.TgzArchiveType[source]

.tgz archive type

EXTENSION = '.tgz'
class rebasehelper.archive.ZipArchiveType[source]

.zip archive type

EXTENSION = '.zip'
classmethod extract(archive=None, filename=None, path=None, *args, **kwargs)[source]
classmethod match(filename=None)[source]
classmethod open(filename=None)[source]
rebasehelper.archive.register_archive_type(archive)[source]

Build helper module

exception rebasehelper.build_helper.BinaryPackageBuildError(*args, **kwargs)[source]

Error indicating failure to build Binary Package

class rebasehelper.build_helper.BuildTemporaryEnvironment(sources, patches, spec, results_dir)[source]

Class representing temporary environment.

TEMPDIR_RESULTS = 'TEMPDIR_RESULTS'
TEMPDIR_SOURCES = 'TEMPDIR_SOURCES'
TEMPDIR_SPEC = 'TEMPDIR_SPEC'
TEMPDIR_SPECS = 'TEMPDIR_SPECS'
class rebasehelper.build_helper.BuildToolBase[source]

Base class for various build tools

DEFAULT = False
classmethod accepts_options()[source]

Checks if the tool accepts additional command line options.

classmethod build(*args, **kwargs)[source]

Build binaries from the sources.

Keyword arguments: spec – path to a SPEC file sources – list with absolute paths to SOURCES patches – list with absolute paths to PATCHES results_dir – path to DIR where results should be stored

Returns: dict with: ‘srpm’ -> absolute path to SRPM ‘rpm’ -> list of absolute paths to RPMs ‘logs’ -> list of absolute paths to logs

classmethod creates_tasks()[source]

Checks if the tool creates build tasks.

classmethod get_build_tool_name()[source]

Returns the name of the build tool.

static get_builder_options(**kwargs)[source]
classmethod get_detached_task(task_id, results_dir)[source]

Gets packages and logs for specified task

Parameters:
  • task_id – detached task id
  • results_dir – path to DIR where results should be stored
Returns:

tuple with: list of absolute paths to RPMs list of absolute paths to logs

classmethod get_logs()[source]

Get logs from previously failed build Returns: dict with ‘logs’ -> list of absolute paths to logs

static get_srpm_builder_options(**kwargs)[source]
static get_srpm_buildtool(**kwargs)[source]
classmethod get_task_info(build_dict)[source]

Gets information about detached remote task

Parameters:build_dict – build data
Returns:task info
classmethod is_default()[source]

Checks if the tool is the default build tool.

classmethod match(cmd=None, *args, **kwargs)[source]

Checks if tool name matches the desired one.

classmethod prepare(spec, conf)[source]

Prepare for building.

Parameters:spec – spec file object
classmethod wait_for_task(build_dict, results_dir)[source]

Waits until specified task is finished

Parameters:
  • build_dict – build data
  • results_dir – path to DIR where results should be stored
Returns:

tuple with: list of absolute paths to RPMs list of absolute paths to logs

class rebasehelper.build_helper.Builder(tool=None)[source]

Class representing a process of building binaries from sources.

accepts_options()[source]
build(*args, **kwargs)[source]

Build sources.

build_tools = {'copr': <class 'rebasehelper.build_tools.copr_tool.CoprBuildTool'>, 'rpmbuild': <class 'rebasehelper.build_tools.rpmbuild_tool.RpmbuildBuildTool'>, 'mock': <class 'rebasehelper.build_tools.mock_tool.MockBuildTool'>}
creates_tasks()[source]
classmethod get_default_tool()[source]

Returns default build tool

get_detached_task(task_id, results_dir)[source]

Get detached task

get_logs()[source]

Get logs.

classmethod get_supported_tools()[source]

Returns a list of supported build tools

Returns:list of supported build tools
get_task_info(build_dict)[source]

Get task info

classmethod load_build_tools()[source]
prepare(spec, conf)[source]

Prepare for build

wait_for_task(build_dict, results_dir)[source]

Wait for task

class rebasehelper.build_helper.RpmbuildTemporaryEnvironment(sources, patches, spec, results_dir)[source]

Class representing temporary environment for RpmbuildBuildTool.

TEMPDIR_BUILD = 'TEMPDIR_BUILD'
TEMPDIR_BUILDROOT = 'TEMPDIR_BUILDROOT'
TEMPDIR_RPMBUILD = 'TEMPDIR_RPMBUILD'
TEMPDIR_RPMS = 'TEMPDIR_RPMS'
TEMPDIR_SRPMS = 'TEMPDIR_SRPMS'
class rebasehelper.build_helper.SRPMBuildToolBase[source]

Base class for SRPM builder tools

DEFAULT = False
classmethod build_srpm(spec, workdir, results_dir, srpm_builder_options)[source]

Build SRPM with chosen SRPM Build Tool

Parameters:
  • spec – abs path to SPEC file inside the rpmbuild/SPECS in workdir.
  • workdir – abs path to working directory with rpmbuild directory structure, which will be used as HOME dir.
  • results_dir – abs path to dir where the log should be placed.
  • srpm_builder_options – list of additional options to rpmbuild.
Returns:

If build process ends successfully returns abs path to built SRPM, otherwise ‘None’.

classmethod get_build_tool_name()[source]

Returns name of the SRPM Build Tool

classmethod is_default()[source]

Returns true if the SRPM Build Tool is set to be default

class rebasehelper.build_helper.SRPMBuilder[source]

Builder class for building SRPMs.

classmethod get_default_tool()[source]

Returns default build tool

classmethod get_supported_tools()[source]

Returns list of supported srpm build tools

classmethod load_srpm_build_tools()[source]
srpm_build_tools = {'rpmbuild': <class 'rebasehelper.srpm_build_tools.rpmbuild_tool.RpmbuildSRPMBuildTool'>, 'mock': <class 'rebasehelper.srpm_build_tools.mock_tool.MockSRPMBuildTool'>}
exception rebasehelper.build_helper.SourcePackageBuildError(*args, **kwargs)[source]

Error indicating failure to build Source Package.

CLI module

class rebasehelper.cli.CLI(args=None)[source]

Class for processing data from commandline

static build_parser()[source]
class rebasehelper.cli.CliHelper[source]
static run()[source]
class rebasehelper.cli.CustomAction(option_strings, switch=False, actual_default=None, dest=None, default=None, nargs=None, required=False, type=None, metavar=None, help=None, choices=None)[source]
class rebasehelper.cli.CustomArgumentParser(prog=None, usage=None, description=None, epilog=None, version=None, parents=[], formatter_class=<class 'argparse.HelpFormatter'>, prefix_chars='-', fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', add_help=True)[source]
error(message)[source]
class rebasehelper.cli.CustomHelpFormatter(prog, indent_increment=2, max_help_position=24, width=None)[source]

Exception module

exception rebasehelper.exceptions.CheckerNotFoundError[source]

Error indicating failure unable to find checker binary.

exception rebasehelper.exceptions.RebaseHelperError(*args, **kwargs)[source]

Class representing Error raised inside rebase-helper after intentionally catching some expected and well known exception/error.

Logger module

class rebasehelper.logger.LoggerHelper[source]

Helper class for setting up a logger

static add_file_handler(logger, path, formatter=None, level=None)[source]

Adds FileHandler to a given logger

Parameters:
  • logger – Logger object to which the file handler will be added
  • path – Path to file where the debug log will be written
Returns:

None

static add_stream_handler(logger, level=None)[source]

Adds console handler with given severity.

Parameters:
  • logger – logger object to add the handler to
  • level – severity level
Returns:

created handler object

static get_basic_logger(logger_name, level=10)[source]

Sets-up a basic logger without any handler

Parameters:
  • logger_name – Logger name
  • level – severity level
Returns:

created logger

Ouptut tool module

class rebasehelper.output_tool.BaseOutputTool[source]

Base class for OutputTools. print_cli_summary must be overridden in order to produce different CLI output

DEFAULT = False
EXTENSION = 'ext'
NAME = 'name'
static get_default_tool()[source]

Returns default output tool

classmethod get_extension()[source]
classmethod get_name()[source]
classmethod get_report_path(app)[source]
static get_supported_tools()[source]

Returns list of supported output tools

classmethod match(cmd=None)[source]

Checks if tool name matches the desired one.

classmethod print_cli_summary(app)[source]

Print report of the rebase

Parameters:app – Application instance
classmethod print_patches_cli()[source]

Print info about patches

classmethod print_patches_section_cli(color, patch_type)[source]

Print info about one of the patches key section

Parameters:
  • color – color used for the message printing
  • patch_type – string containing key for the patch_dict
classmethod print_report_file_path()[source]

Print path to the report file

classmethod run()[source]
class rebasehelper.output_tool.OutputToolRunner[source]

Class representing the process of running various output tools.

run_output_tools(logs=None, app=None)[source]

Runs all output tools.

Parameters:
  • log – Log that probably contains the important message concerning the rebase fail
  • app – Application class instance

Patch helper module

class rebasehelper.patch_helper.GitPatchTool[source]

Class for git command used for patching old and new sources

CMD = 'git'
classmethod apply_old_patches()[source]

Function applies a patch to a old/new sources

static apply_patch(repo, patch_object)[source]

Function applies patches to old sources It tries apply patch with am command and if it fails then with command –apply

classmethod call_prep_script(prep_script_path)[source]
classmethod create_prep_script(prep)[source]

Function abstract special things from prep section and apply them to old sources

diff_cls = None
exec_prep_script = False
classmethod init_git(directory)[source]

Function initialize old and new Git repository

classmethod match(cmd=None)[source]
new_repo = None
new_sources = ''
non_interactive = False
old_repo = None
old_sources = ''
output_data = None
patch_sources_by_prep_script = False
patches = None
prep_section = False
classmethod run_patch(old_dir, new_dir, rest_sources, patches, prep, **kwargs)[source]

The function can be used for patching one directory against another

source_dir = ''
class rebasehelper.patch_helper.PatchBase[source]

Class used for using several patching command tools, … Each method should overwrite method like run_check

classmethod match(cmd=None, *args, **kwargs)[source]

Method checks whether it is usefull patch method

classmethod run_patch(old_dir, new_dir, rest_sources, git_helper, patches, *args, **kwargs)[source]

Method will check all patches in relevant package

class rebasehelper.patch_helper.Patcher(tool=None)[source]

Class representing a process of applying and generating rebased patch using specific tool.

patch(old_dir, new_dir, rest_sources, patches, prep, **kwargs)[source]

Apply patches and generate rebased patches if needed

Parameters:
  • old_dir – path to dir with old patches
  • new_dir – path to dir with new patches
  • patches – old patches
  • rebased_patches – rebased patches
  • kwargs

Returns:

rebasehelper.patch_helper.register_patch_tool(patch_tool)[source]

Specfile module

class rebasehelper.specfile.BaseSpecHook[source]

Base class for a spec hook

classmethod get_categories()[source]

Returns list of categories of a spec hook

classmethod get_name()[source]

Returns the name of a spec hook

classmethod run(spec_file, rebase_spec_file, **kwargs)[source]

Runs a spec hook.

Parameters:
  • spec_file – Original spec file object
  • rebase_spec_file – Rebased spec file object
  • kwargs – Keyword arguments from Application instance
class rebasehelper.specfile.PatchList[source]
class rebasehelper.specfile.PatchObject(path, index, option)[source]

Class represents set of information about patches

get_index()[source]
get_option()[source]
get_patch_name()[source]
get_path()[source]
git_generated = ''
index = ''
option = ''
path = ''
set_path(new_path)[source]
class rebasehelper.specfile.SpecFile(path, changelog_entry, sources_location='', download=True)[source]

Class representing a SPEC file

category = None
static construct_string_with_comment(lines)[source]

Wraps the line in a rebase-helper specific comments

Parameters:lines – line (or list of lines) to be wrapped
Returns:list with lines
copy(new_path=None)[source]

Create a copy of the current object and copy the SPEC file the new object represents to a new location.

Parameters:new_path – new path to which to copy the SPEC file
Returns:copy of the current object
defined_sections = ['%package', '%description', '%prep', '%build', '%install', '%check', '%files', '%changelog']
download = False
download_remote_sources()[source]

Method that iterates over all sources and downloads ones, which contain URL instead of just a file.

Returns:None
extra_version = None
static extract_version_from_archive_name(archive_path, source_string='')[source]

Method extracts the version from archive name based on the source string from SPEC file. It extracts also an extra version such as ‘b1’, ‘rc1’, …

Parameters:
  • archive_path – archive name or path with archive name from which to extract the version
  • source_string – Source string from SPEC file used to construct version extraction regex
Returns:

tuple of strings with (extracted version, extra version) or (None, None) if extraction failed

find_archive_target_in_prep(archive)[source]

Tries to find a command that is used to extract the specified archive and attempts to determine target path from it. ‘tar’ and ‘unzip’ commands are supported so far.

Parameters:archive – Path to archive
Returns:Target path relative to builddir or None if not determined
get_applied_patches()[source]

Method returns list of all applied patches.

Returns:list of PatchObject
get_archive()[source]

Method returns the basename of first Source in SPEC file a.k.a. Source0

Returns:basename of first Source in SPEC file
Return type:str
get_epoch_number()[source]

Method for getting epoch of the package

Returns:
get_extra_version()[source]

Returns an extra version of the package - like b1, rc2, …

Returns:String
get_extra_version_separator()[source]

Returns the separator between version and extra version as used by upstream. If there is not separator or extra version, it returns an empty string.

Returns:String with the separator between version as extra version as used by upstream.
Return type:str
get_full_version()[source]

Returns the full version string, which is a combination of version, separator and extra version.

Returns:String with full version, including the extra version part.
Return type:str
get_new_log()[source]
get_not_used_patches()[source]

Method returns list of all unpplied patches.

Returns:list of PatchObject
get_package_name()[source]

Function returns a package name

Returns:
get_patch_option(line)[source]

Function returns a patch options

Parameters:line
Returns:patch options like -p1
get_patches()[source]

Method returns list of all applied and not applied patches

Returns:list of PatchObject
get_path()[source]

Return only spec file path

Returns:
static get_paths_with_rpm_macros(files)[source]

Method modifies paths in passed list to use RPM macros

Parameters:files – list of absolute paths
Returns:modified list of paths with RPM macros
get_prep_section(complete=False)[source]

Function returns whole prep section

get_release()[source]

Method for getting full release string of the package

Returns:
get_release_number()[source]

Method for getting the release of the package

Returns:
get_requires()[source]

Function returns a package requirements

Returns:
get_setup_dirname()[source]

Get dirname from %setup or %autosetup macro arguments

Returns:dirname
get_sources()[source]

Method returns dictionary with local sources list.

Returns:list of Sources with absolute path
Return type:list of str
get_spec_section(section_name)[source]

Returns the section of selected name

Parameters:section_name – section name to get
Returns:list of lines contained in the selected section
get_version()[source]

Method returns the version

Returns:
hdr = None
insert_changelog(new_log)[source]
is_test_suite_enabled()[source]

Returns whether test suite is enabled during the build time

Returns:True if enabled or False if not
modify_spec_files_section(files)[source]

Function repairs spec file according to new sources.

Parameters:files
Returns:
patches = None
path = ''
prep_section = []
redefine_release_with_macro(macro)[source]

Method redefines the Release: line to include passed macro and comments out the old line

Parameters:macro
Returns:
removed_patches = []
revert_redefine_release_with_macro(macro)[source]

Method removes the redefined the Release: line with given macro and uncomments the old Release line.

Parameters:macro
Returns:
rpm_sections = {}
save()[source]

Save changes made to the spec_content to the disc and update internal variables

set_extra_version(extra_version)[source]

Method to update the extra version in the SPEC file. Redefined Source0 if needed and also changes Release accordingly.

Parameters:extra_version – the extra version string, if any (e.g. ‘b1’, ‘rc2’, …)
Returns:None
set_extra_version_separator(separator)[source]

Set the string that separates the version and extra version

Parameters:separator
Returns:
set_release_number(release)[source]

Method to set release number

Parameters:release
Returns:
set_spec_section(section_name, new_section)[source]

Returns the section of selected name

Parameters:section_name – section name to get
Returns:list of lines contained in the selected section
set_tag(tag, value, preserve_macros=False)[source]

Sets value of a tag while trying to preserve macros if requested

set_version(version)[source]

Method to update the version in the SPEC file

Parameters:version – string with new version
Returns:None
set_version_using_archive(archive_path)[source]

Method to update the version in the SPEC file using a archive path. The version is extracted from the archive name.

Parameters:archive_path
Returns:
sources = None
spc = None
spec_content = []
static split_version_string(version_string='')[source]

Method splits version string into version and possibly extra string as ‘rc1’ or ‘b1’, …

Parameters:version_string – version string such as ‘1.1.1’ or ‘1.2.3b1’, …
Returns:tuple of strings with (extracted version, extra version, separator) or (None, None, None) if extraction failed
update_changelog(new_log)[source]

Function updates changelog with new version

update_paths_to_patches()[source]
update_setup_dirname(dirname)[source]

Update %setup or %autosetup dirname argument if needed

Parameters:dirname – new dirname to be used
write_updated_patches(patches, disable_inapplicable)[source]

Function writes the patches to -rebase.spec file

class rebasehelper.specfile.SpecHooksRunner[source]

Class representing the process of running various spec file hooks.

get_available_spec_hooks()[source]

Returns a list of all available spec hooks

run_spec_hooks(spec_file, rebase_spec_file, **kwargs)[source]

Runs all spec hooks.

Parameters:
  • spec_file – Original spec file object
  • rebase_spec_file – Rebased spec file object
  • kwargs – Keyword arguments from Application instance
rebasehelper.specfile.get_rebase_name(dir_name, name)[source]

Function returns a name in results directory

Parameters:
  • dir_name
  • name
Returns:

full path to results dir with name

Utils module

class rebasehelper.utils.ConsoleHelper[source]

Class for command line interaction with the user.

class Capturer(stdout=False, stderr=False)[source]

ContextManager for capturing stdout/stderr

classmethod cprint(message, color=None)[source]

Print colored output if possible

Parameters:
  • color – color to be used in the output
  • message – string to be printed out
static get_message(message, default_yes=True, any_input=False)[source]

Function for command line messages

Parameters:
  • message – prompt string
  • default_yes – If the default value is YES
  • any_input – if True, return input without checking it first
Returns:

True or False, based on user’s input

classmethod should_use_colors(conf)[source]

Determine whether ansi colors should be used for CLI output

use_colors = False
class rebasehelper.utils.CoprHelper[source]
classmethod build(client, project, srpm)[source]
classmethod create_project(client, project, chroot, description, instructions)[source]
classmethod download_build(client, build_id, destination)[source]
classmethod get_build_status(client, build_id)[source]
classmethod get_build_url(client, build_id)[source]
classmethod get_client()[source]
classmethod watch_build(client, build_id)[source]
exception rebasehelper.utils.DownloadError[source]

Exception indicating that download of a file failed.

class rebasehelper.utils.DownloadHelper[source]

Class for downloading sources defined in SPEC file

static download_file(url, destination_path, timeout=10, blocksize=8192)[source]

Method for downloading file from HTTP, HTTPS and FTP URL.

Parameters:
  • url – URL from which to download the file
  • destination_path – path where to store downloaded file
  • timeout – timeout in seconds for blocking actions like connecting, etc.
  • blocksize – size in Bytes of blocks used for downloading the file and reporting progress
Returns:

None

static progress(download_total, downloaded, start_time)[source]

The function prints download progress and remaining time of the download directly to the standard output.

Parameters:
  • download_total (int or float) – size of the file which is being downloaded
  • downloaded (int or float) – already downloaded size of the file
  • start_time (float) – time in seconds since the epoch from the point when the download started. This is used to calculate the remaining time of the download.
Returns:

None

class rebasehelper.utils.FileHelper[source]
static file_available(filename)[source]
class rebasehelper.utils.GitHelper[source]

Class which operates with git repositories

GIT_USER_EMAIL = 'rebase-helper@localhost.local'
GIT_USER_NAME = 'rebase-helper'
classmethod get_email()[source]
classmethod get_user()[source]
classmethod run_mergetool(repo)[source]
exception rebasehelper.utils.GitRebaseError[source]

Error indicating problems with Git

exception rebasehelper.utils.GitRuntimeError[source]

Error indicating problems with Git

class rebasehelper.utils.KojiHelper[source]
baseurl = 'http://kojipkgs.fedoraproject.org/work/'
baseurl_pkg = 'https://kojipkgs.fedoraproject.org/packages/'
ca_cert = '/home/docs/.fedora-server-ca.cert'
cert = '/home/docs/.fedora.cert'
classmethod display_task_results(tasks)[source]

Taken from from koji_cli.lib

classmethod download_build(build_id, destination)[source]

Downloads all x86_64 RPMs and logs of a Koji build

Parameters:
  • build_id – Koji build ID
  • destination – target path
Returns:

(list of paths to RPMs, list of paths to logs)

classmethod download_scratch_build(session, task_list, dir_name)[source]
functional = False
classmethod get_koji_tasks(task_id, dir_name)[source]
classmethod get_latest_build(package)[source]

Searches for the latest Koji build of a package

Parameters:package – package name
Returns:(latest version, Koji build ID)
koji_web = 'koji.fedoraproject.org'
scratch_url = 'http://koji.fedoraproject.org/work/'
server = 'https://koji.fedoraproject.org/kojihub'
classmethod session_maker(baseurl=None)[source]
classmethod upload_srpm(session, source)[source]
classmethod watch_koji_tasks(session, tasklist)[source]

Taken from from koji_cli.lib

exception rebasehelper.utils.LookasideCacheError[source]

Exception indicating a problem accessing lookaside cache

class rebasehelper.utils.LookasideCacheHelper[source]

Class for downloading files from Fedora/RHEL lookaside cache

classmethod download(tool, basepath, package)[source]
rpkg_config_dir = '/etc/rpkg'
class rebasehelper.utils.MacroHelper[source]

Helper class for working with RPM macros

static dump()[source]

Returns list of all defined macros

Returns:list of macros
static expand(s, default=None)[source]
static filter(macros, **kwargs)[source]

Returns all macros satisfying specified filters

Parameters:
  • macros – list of macros to be filtered
  • kwargs – filters
Returns:

filtered list of macros

class rebasehelper.utils.PathHelper[source]

Class which finds a file or files in specific directory

static find_all_files(top_path, pattern)[source]

Finds a file that matches the given ‘pattern’ recursively starting in the ‘top_path’ directory. If found, returns full path to the first occurrence of the file, otherwise returns None.

static find_all_files_current_dir(top_path, pattern)[source]

Finds all files that matches the given ‘pattern’ in the ‘top_path’ directory. If found, returns fields of all files, otherwise returns None.

static find_first_dir_with_file(top_path, pattern)[source]

Finds a file that matches the given ‘pattern’ recursively starting in the ‘top_path’ directory. If found, returns full path to the directory with first occurrence of the file, otherwise returns None.

static find_first_file(top_path, pattern, recursion_level=None)[source]

Finds a file that matches the given ‘pattern’ recursively starting in the ‘top_path’ directory. If found, returns full path to the first occurrence of the file, otherwise returns None.

static get_temp_dir()[source]

Returns a path to new temporary directory.

class rebasehelper.utils.ProcessHelper[source]

Class for execution subprocess

DEV_NULL = '/dev/null'
static run_subprocess(cmd, input=None, output=None)[source]

Runs the passed command as a subprocess.

Parameters:
  • cmd – command with arguments to be run
  • input – file to read the input from. If None, read from STDIN
  • output – file to write the output of the command. If None, write to STDOUT
Returns:

exit code of the process

static run_subprocess_cwd(cmd, cwd=None, input=None, output=None, shell=False)[source]

Runs the passed command as a subprocess in different working directory.

Parameters:
  • cmd – command with arguments to be run
  • cwd – the directory to change the working dir to
  • input – file to read the input from. If None, read from STDIN
  • output – file to write the output of the command. If None, write to STDOUT
  • shell – if to run the command as shell command (default: False)
Returns:

exit code of the process

static run_subprocess_cwd_env(cmd, cwd=None, env=None, input=None, output=None, shell=False)[source]

Runs the passed command as a subprocess in different working directory with possibly changed ENVIRONMENT VARIABLES.

Parameters:
  • cmd – command with arguments to be run
  • cwd – the directory to change the working dir to
  • env – dictionary with ENVIRONMENT VARIABLES to define
  • input – file to read the input from. If None, read from STDIN
  • output – file to write the output of the command. If None, write to STDOUT
  • shell – if to run the command as shell command (default: False)
Returns:

exit code of the process

static run_subprocess_env(cmd, env=None, input=None, output=None, shell=False)[source]

Runs the passed command as a subprocess with possibly changed ENVIRONMENT VARIABLES.

Parameters:
  • cmd – command with arguments to be run
  • env – dictionary with ENVIRONMENT VARIABLES to define
  • input – file to read the input from. If None, read from STDIN
  • output – file to write the output of the command. If None, write to STDOUT
  • shell – if to run the command as shell command (default: False)
Returns:

exit code of the process

class rebasehelper.utils.RpmHelper[source]

Helper class for doing various tasks with RPM database, packages, …

ARCHES = None
static all_packages_installed(pkg_names=None)[source]

Check if all packages in passed list are installed.

Parameters:pkg_names – iterable with package named to check for
Returns:True if all packages are installed, False if at least one package is not installed.
static get_arches()[source]

Get list of all known architectures

static get_header_from_rpm(rpm_name)[source]

Function returns a rpm header from given rpm package for later on analysis

Parameters:rpm_name
Returns:
static get_info_from_rpm(rpm_name, info)[source]

Method returns a name of the package from RPM file format

Parameters:pkg_name
Returns:
static install_build_dependencies(spec_path=None, assume_yes=False)[source]

Install all build requires for a package using PolicyKits

Parameters:spec_path – absolute path to SPEC file
Returns:
static is_package_installed(pkg_name=None)[source]

Checks whether package with passed name is installed.

Parameters:package_name – package name we want to check for
Returns:True if installed, False if not installed
classmethod parse_spec(path)[source]
classmethod split_nevra(string)[source]

Splits string into name, epoch, version, release and arch components

class rebasehelper.utils.TemporaryEnvironment(exit_callback=None, **kwargs)[source]

Class representing a temporary environment (directory) that can be used as a workspace. It can be used with with statement.

TEMPDIR = 'TEMPDIR'
env()[source]

Returns copy of _env dictionary.

Returns:copy of _env dictionary
path()[source]

Returns path to the temporary environment.

Returns:abs path to the environment
rebasehelper.utils.get_value_from_kwargs(kwargs, field, source='old')[source]

Function returns a part of self.kwargs dictionary

Parameters:
  • kwargs
  • source – ‘old’ or ‘new’
  • field – like ‘patches’, ‘source’
Returns:

value from dictionary

Change Log

[Unreleased]

[0.11.0] - 2017-10-04

Added
  • Added rpm-py-installer to install rpm-python from pip
  • Implemented detection of package category (python, perl, ruby, nodejs, php)
  • Added RubyGems versioneer
  • Added RubyHelper SPEC hook for getting additional sources based on instructions in SPEC file comments
Changed
  • Value of Version and Release tags is now preserved if there are any macros that can be modified instead
  • Versioneers and SPEC hooks are now run only for matching package categories
  • Bash completion is now generated from source code, so it is always up-to-date
Fixed
  • Prevented unwanted modifications of %prep section
  • Fixed unexpected removal of rpms and build logs after last build retry
  • Added files are no longer listed as removed in rpmdiff report

[0.10.1] - 2017-08-30

Added
  • Added --version argument
Changed
  • Anitya versioneer now primarily searches for projects using Fedora mapping
  • Python dependencies moved from requirements.txt to setup.py
Fixed
  • Made CustomManPagesBuilder work with Sphinx >= 1.6
  • %prep section parser is now able to handle backslash-split lines

[0.10.0] - 2017-08-25

Added
  • Implemented extensible SPEC hooks and versioneers
  • Added PyPI SPEC hook for automatic fixing of Source URL of Python packages
  • Added Anitya and PyPI versioneers for determining latest upstream version of a package
  • Added possibility to download old version build of a package from Koji
  • Added support for test suite to be run in Docker containers
  • Implemented functional tests for automatic testing of whole rebase process
  • Diff against original source files is now generated as changes.patch
Changed
  • Introduced plugin system for extending build tools, checkers and output tools
  • Updated for Koji 1.13 which finally brings Python 3 support
  • Improved output information and reports
  • Added colorized output
  • Improved project documentation
Fixed
  • Pre-configured git username and e-mail address is now used if available
  • Fixed several issues in rpmdiff and especially abipkgdiff checkers
  • Fixed several test suite related issues

[0.9.0] - 2017-01-05

Added
  • Old sources are now downloaded from Fedora lookaside cache
  • Auto-generated and improved CLI documentation and man page
  • Added support for downloading files of unknown size
Changed
  • SpecFile class preparation for pre-download hooks
  • Code cleanup and refactorization
Fixed
  • Fixed regexp for getting release number from SPEC
  • Fixed functionality of --results-dir option
  • Several upstream monitoring fixes
  • Fixed issues caused by Fedora Flag Day

[0.8.0] - 2016-07-31

Added
  • Added support for JSON output format
  • Added support for copr build tool
  • Added support for passing arbitrary extra arguments to local builders (mock, rpmbuild) with --builder-options.
  • Added new option --build-retries allows the user to specify number of build retries (by default 2)
  • Added support for csmock check tool
Changed
  • Renamed fedpkg build tool to koji to make it more clear
  • Downloading of files is now done only using standard Python library and not using PyCURL
Fixed
  • Many bug fixes and code clean up

[0.7.3] - 2016-04-08

Added
  • Added rpm.addMacro
Fixed
  • Handled exceptions raised during parsing of SPEC files
  • Fixed unapplied patches mixing with deleted ones

[0.7.2] - 2016-03-15

Added
  • Added information about scratch builds
Fixed
  • Added check if file exists and is empty for the-new-hotness
  • Patches are applied in case --builds-nowait option is used

[0.7.1] - 2016-02-22

Added
  • Two new command line options used by upstream monitoring
Fixed
  • fedpkg reimplementation

[0.7.0] - 2016-01-13

Changed
  • Several improvements
Fixed
  • pkgdiff is now smarter
  • Included tar.bz2 into list of supported formats
  • Added support for noarch package in case of fedpkg build
  • Checker should return None if there is no debug package
Removed
  • Removed a bunch of debug stuff

[0.6.2] - 2015-11-09

Fixed
  • Logs are being saved to their own directory
  • Prep script is moved into workspace directory
  • No more traceback in case koji module is not present
  • Each checker creates its own log file
  • rebase-helper informs if it failed or not
  • Report on script is smarter

[0.6.1] - 2015-10-30

Added
  • upstream-monitoring.py - used by upstream monitoring service
  • rebase-helper-fedmsg.py - testing Python script

[0.6.0] - 2015-07-31

Added
  • Parts of %prep section related to patching are executed
  • Support for abipkgdiff
Fixed
  • Several fixes
  • Replaced yum with dnf

[0.5.0] - 2015-05-22

Added
  • Added support for building packages via fedpkg (or koji)
  • Added summary report for better overview
  • continue option implemented for git rebase
  • Added several tests
  • Added class for operating with Git repositories
Changed
  • git rebase is used instead of patch command
Fixed
  • Fixed several decoding issues
  • Several PEP8 and W1202 fixes
Removed
  • DiffHelper class is not needed

[0.4.0] - 2014-12-05

Added
  • Handling of extra versions like b1, rc1, etc.
  • Added build log analyzer to detect unpackaged files or other issues
  • Added Bash completion
Changed
  • Improved version extraction from archive name
  • rebase-helper output is looged to rebase-helper-results directory
  • SpecFile class rewritten

[0.3.1] - 2014-07-25

Added
  • New build class
  • --build-only option
  • Installation of build dependencies in case of rpmbuild tool
  • More tests
  • RebaseHelperError class for catching exceptions
Fixed
  • Several fixes

[0.3.0]

Added
  • pkgdiff tool for comparing RPM packages
  • Tests for Archive class and SPEC file

[0.2.0]

Added
  • diff_helper for comparing two tarballs
  • Applying patches to tarballs
  • patch_helper

[0.1.0]

Added
  • Initial classes
  • CLI interface