Example #1
0
    def rev(self) -> str:
        """
        This method determines which revision the bzr repository associated with this
        :py:class:`BzrSource` currently is at and returns it as a string. Once run, it saves the
        last processed revision number in `self.saved_rev`, in case the revision needs to be
        determined when bzr repository might not be accessible anymore (e.g. if `bzr.keep=False` is
        set in configuration, so the repository is not kept after export to tarball).

        Returns:
            str: either revision string from repo, last stored rev string or `""` when unsuccessful
        """

        # ktr = Kentauros()
        logger = KtrLogger(LOG_PREFIX)

        # if sources are not accessible (anymore), return "" or last saved rev
        if not os.access(self.dest, os.R_OK):
            if self.saved_rev is None:
                logger.dbg("Sources need to be get before rev can be determined.")
                return ""
            else:
                return self.saved_rev

        cmd = ["bzr", "revno"]

        prev_dir = os.getcwd()
        os.chdir(self.dest)

        logger.log_command(cmd, 0)
        rev = subprocess.check_output(cmd).decode().rstrip("\n")

        os.chdir(prev_dir)

        self.saved_rev = rev
        return rev
Example #2
0
    def commit(self) -> str:
        """
        This method provides an easy way of getting the commit hash of the requested commit. It
        also stores the latest commit hash between method invocations, if the source goes away and
        the hash is needed again.

        Returns:
            str:        commit hash
        """

        logger = KtrLogger(LOG_PREFIX)

        # if sources are not accessible (anymore), return None or last saved rev
        if not os.access(self.dest, os.R_OK):
            if self.saved_commit is None:
                logger.dbg("Sources need to be get before commit hash can be read.")
                return None
            else:
                return self.saved_commit

        cmd = ["git", "rev-parse", "HEAD"]

        prev_dir = os.getcwd()
        os.chdir(self.dest)

        logger.log_command(cmd, 1)
        rev = subprocess.check_output(cmd).decode().rstrip("\n")

        os.chdir(prev_dir)

        self.saved_commit = rev
        return rev
Example #3
0
    def _get_last_release(self, spec: RPMSpec):
        """
        This method tries to read the latest state from the state database - if that is not
        available, the .spec file is parsed as a fallback.

        Arguments:
            RPMSpec spec:   rpm spec object

        Returns:
            str:            last known release
        """

        assert isinstance(spec, RPMSpec)

        ktr = Kentauros()
        logger = KtrLogger(LOG_PREFIX)

        saved_state = ktr.state_read(self.cpkg.get_conf_name())

        if saved_state is None:
            logger.dbg("Package " +
                       self.cpkg.get_conf_name() +
                       " not yet in state database.")
            logger.dbg("Falling back to legacy release detection.")
            old_release = spec.get_release()
        elif "rpm_last_release" not in saved_state:
            logger.dbg("Package " +
                       self.cpkg.get_conf_name() +
                       " has no release set in state database.")
            logger.dbg("Falling back to legacy release detection.")
            old_release = spec.get_release()
        else:
            old_release = saved_state["rpm_last_release"]

        return old_release
Example #4
0
def print_parameters():
    """
    This function prints the general execution parameters.
    """

    ktr = Kentauros()
    logger = KtrLogger(LOG_PREFIX)

    print_flush()

    logger.log("Debugging:                          " + str(ktr.debug), 0)
    logger.log("Logger Verbosity:                   " + str(ktr.verby) + "/2", 1)

    print_flush()

    logger.dbg("Base directory:                     " + ktr.conf.basedir)
    logger.dbg("Package configuration directory:    " + ktr.conf.get_confdir())
    logger.dbg("Package sources directory:          " + ktr.conf.get_datadir())
    logger.dbg("Binary package directory:           " + ktr.conf.get_expodir())
    logger.dbg("Source package directory:           " + ktr.conf.get_packdir())
    logger.dbg("Package specification directory:    " + ktr.conf.get_specdir())

    print_flush()
Example #5
0
    def prepare(self) -> bool:
        """
        This method prepares all files necessary for source package assembly.

        This includes

        - copying every file (not directories) from package source directory to `rpmbuild/SOURCES`,
        - removing the latest tarball from the package source directory if it should not be kept,
        - copying the package configuration file to `rpmbuild/SOURCES`
        - preparing the `package.spec` file in `rpmbuild/SPECS` from the file in the spec directory,
        - defining macros for git and bzr version string additions,
        - setting `Version:` and `Release:` tags according to configuration,
        - appending a changelog entry automatically for every different build,
        - copying back the modified spec file to preserve added changelog entries.

        Returns:
            bool:           returns `True` if the preparation was successful.
        """

        ktr = Kentauros()
        logger = KtrLogger(LOG_PREFIX)

        spec = RPMSpec(self.path, self.cpkg.get_module("source"))

        if not os.path.exists(self.rpmbdir):
            warnings.warn("Make sure to call Constructor.init() before .prepare()!", Warning)
            self.init()

        # copy sources to rpmbuild/SOURCES
        for entry in os.listdir(self.cpkg.get_module("source").sdir):
            entry_path = os.path.join(self.cpkg.get_module("source").sdir, entry)
            if os.path.isfile(entry_path):
                shutil.copy2(entry_path, self.srcsdir)
                logger.log("File copied to SOURCES: " + entry_path, 1)

        # remove tarballs if they should not be kept
        if not self.cpkg.get_module("source").get_keep():

            # if source is a tarball (or similar) from the beginning:
            if os.path.isfile(self.cpkg.get_module("source").dest):
                os.remove(self.cpkg.get_module("source").dest)

            # otherwise it is in kentauros' standard .tar.gz format:
            else:
                tarballs = glob.glob(os.path.join(self.cpkg.get_module("source").sdir,
                                                  self.cpkg.get_name()) + "*.tar.gz")
                # remove only the newest one to be safe
                tarballs.sort(reverse=True)
                if os.path.isfile(tarballs[0]):
                    assert self.cpkg.get_module("source").sdir in tarballs[0]
                    os.remove(tarballs[0])
                    logger.log("Tarball removed: " + tarballs[0], 1)

        # copy package.conf to rpmbuild/SOURCES
        shutil.copy2(self.cpkg.file, self.srcsdir)
        logger.log("Package configuration copied to SOURCES: " + self.cpkg.file, 1)

        # construct preamble and new version string
        old_version = self._get_last_version(spec)
        old_release = self._get_last_release(spec)
        new_version = self.cpkg.get_version()

        # TODO: check if release resetting / incrementing logic works now

        spec.set_version()
        spec.set_source()

        # if old version and new version are different, force release reset to 0
        rel_reset = (new_version != old_version)

        # start constructing release string from old release string
        if rel_reset:
            spec.do_release_reset()

        # write preamble to new spec file
        preamble = spec.build_preamble_string()

        # calculate absolute path of new spec file and copy it over
        new_spec_path = os.path.join(self.specdir, self.cpkg.get_name() + ".spec")
        spec.export_to_file(new_spec_path)

        # use "rpmdev-bumpspec" to increment release number and create changelog entries
        force = ktr.cli.get_force()

        logger.dbg("Old Version: " + old_version)
        logger.dbg("New Version: " + new_version)
        logger.dbg("Old Release: " + old_release)

        # if major version has changed, put it into the changelog
        if (old_version != new_version) or (old_release[0] == "0"):
            do_release_bump(new_spec_path,
                            "Update to version " + self.cpkg.get_version() + ".")
            new_rpm_spec = RPMSpec(new_spec_path, self.cpkg.get_module("source"))

        # else if nothing changed but "force" was set (packaging changes)
        # old_version =!= new_version, rel_reset !=!= True
        elif force:
            message = ktr.cli.get_message()
            if message is None:
                do_release_bump(new_spec_path, "Update for packaging changes.")
            else:
                do_release_bump(new_spec_path, message)

            new_rpm_spec = RPMSpec(new_spec_path, self.cpkg.get_module("source"))

        # else if version has not changed, but snapshot has been updated:
        # old_version =!= new_version
        elif rel_reset:
            new_rpm_spec = RPMSpec(new_spec_path, self.cpkg.get_module("source"))
            new_rpm_spec.do_release_reset()
            do_release_bump(new_spec_path, "Update to latest snapshot.")
            new_rpm_spec = RPMSpec(new_spec_path, self.cpkg.get_module("source"))

        else:
            logger.err("Something went wrong.")
            return False

        self.last_release = new_rpm_spec.get_release()
        self.last_version = new_rpm_spec.get_version()

        # copy new spec file back to ktr/specdir to preserve version tracking,
        # release number and changelog consistency (keep old version once as backup)
        # BUT: remove preamble again, it would break things otherwise

        new_rpm_spec.contents = new_rpm_spec.contents.replace(preamble, "")
        shutil.copy2(self.path, self.path + ".old")
        new_rpm_spec.export_to_file(self.path)

        return True
Example #6
0
    def date(self) -> str:
        """
        This method provides an easy way of getting the date and time of the requested commit in a
        standardised format (``YYMMDD.HHmmSS``). It also stores the latest parsed date between
        method invocations, if the source goes away and the commit datetime string is needed again.

        Returns:
            str:        commit date.time string (``YYMMDD.HHmmSS``)
        """

        def prepend_zero(string):
            """
            This local function prepends '0' to one-digit time value strings.
            """

            if len(string) == 1:
                return "0" + string
            else:
                return string

        def date_str_from_raw(raw_date: str):
            """
            This local function parses a datetime object and returns a simple string.
            """

            assert isinstance(raw_date, str)

            date_obj = dateutil.parser.parse(raw_date)

            year_str = str(date_obj.year)[2:]
            month_str = prepend_zero(str(date_obj.month))
            day_str = prepend_zero(str(date_obj.day))

            hour_str = prepend_zero(str(date_obj.hour))
            minute_str = prepend_zero(str(date_obj.minute))
            second_str = prepend_zero(str(date_obj.second))

            date_str = year_str + month_str + day_str + "." + hour_str + minute_str + second_str

            return date_str

        # ktr = Kentauros()
        logger = KtrLogger(LOG_PREFIX)

        # if sources are not accessible (anymore), return None or last saved rev
        if not os.access(self.dest, os.R_OK):
            if self.saved_date is None:
                logger.dbg("Sources need to be get before their age can be read.")
                return None
            else:
                return self.saved_date

        cmd = ["git", "show", "-s", "--date=short", "--format=%cI"]

        prev_dir = os.getcwd()
        os.chdir(self.dest)

        logger.log_command(cmd, 1)
        date_raw = subprocess.check_output(cmd).decode().rstrip('\r\n')

        os.chdir(prev_dir)

        date = date_str_from_raw(date_raw)

        self.saved_date = date
        # ktr.state_write(self.spkg.get_conf_name(), dict(git_last_date=date))

        return date