示例#1
0
    def extract(self):
        retval = subprocess.call(['tar', '-xzf', self.tarballname])
        if retval != 0:
            utils.logerr(None,
                         "Couldn't extract tarball for {}".format(self.name))

        if os.path.exists(self.tarballname):
            os.remove(self.tarballname)
        self.srcdir = os.path.join(self.ctx.builddir, self.name)
示例#2
0
    def cleanup(self):
        if self.srcdir:
            try:
                shutil.rmtree(
                    self.srcdir,
                    onerror=lambda f, p, e: utils.delete_onerror(f, p, e))
            except PermissionError:
                utils.logerr(
                    None,
                    "Cannot remove {}: Permission denied".format(self.srcdir))

            self.srcdir = None  # if we couldn't remove it, we can't next time, so we ignore the exception and continue
示例#3
0
    def get(self):
        if not self.downloaded:
            self.downloaded = True

            # download
            os.chdir(self.ctx.builddir)
            r = requests.get(self.tarballpath)
            with open(self.tarballname, 'wb') as tarball:
                tarball.write(r.content)

            # extract
            retval = subprocess.call(['tar', '-xzf', self.tarballname])
            if retval != 0:
                utils.logerr(
                    None, "Couldn't extract tarball for {}".format(self.name))

            if os.path.exists(self.tarballname):
                os.remove(self.tarballname)
            self.srcdir = os.path.join(self.ctx.builddir, self.name)
示例#4
0
    def build(self, buildflags=['-Cdf'], recursive=False, dependency=False):

        if dependency and self.installed:
            # if this is a dependency and already installed, we do not bother,
            # upgrades are taken care of by -Syu, just as it is common with the official repos
            utils.logmsg(
                self.ctx.v, 3,
                "skipping build of installed dependency {}".format(self.name))
            return True

        if not self.check_makedeps_installed():
            msg = "Makedeps not installed for {}".format(self.name)
            utils.logerr(None, "{}, aborting this subtree".format(msg))
            return False

        if recursive:
            for d in self.deps:
                succeeded = d.build(buildflags=buildflags,
                                    recursive=True,
                                    dependency=True)
                if not succeeded:
                    return False  # one dep fails, the entire branch fails immediately, software will not be runnable

        if self.in_repos or (self.installed and not self.in_aur):
            return True

        if self.installed and self.in_aur and self.version_installed == self.version_latest and not self.rebuild:
            return True

        pkgs = pkg_in_cache(self)
        if len(pkgs) > 0 and not self.rebuild:
            self.built_pkgs.append(
                pkgs[0]
            )  # we only need one of them, not all, if multiple ones with different extensions have been built
            return True

        utils.logmsg(self.ctx.v, 3, "building sources of {}".format(self.name))
        succeeded = self.srcpkg.build(buildflags=buildflags)
        if not succeeded:
            utils.logerr(
                None,
                "Building sources of package {} failed, aborting this subtree".
                format(self.name))
            utils.logerr(None,
                         "├─stdout-log: {}".format(self.srcpkg.stdoutlogfile),
                         primary=False)
            utils.logerr(None,
                         "└─stderr-log: {}".format(self.srcpkg.stderrlogfile),
                         primary=False)
            if self.ctx.printed_error_log_lines > 0:
                utils.logmsg(self.ctx.v, 0, "Tail of stderr:")
                with open(self.srcpkg.stderrlogfile, 'r') as logfile:
                    errorlog = logfile.read().strip().split("\n")
                    for line in errorlog[-self.ctx.printed_error_log_lines:]:
                        print("    {}".format(line))
            if self.ctx.printed_error_log_lines == -1:
                utils.logmsg(self.ctx.v, 0, "stderr:")
                with open(self.srcpkg.stderrlogfile, 'r') as logfile:
                    errorlog = logfile.read().strip().split("\n")
                    for line in errorlog:
                        print("    {}".format(line))

            return False

        pkgext_makepkgconf = subprocess.getoutput(
            "bash -c 'source {} && echo $PKGEXT'".format(self.ctx.makepkgconf))
        pkgext_env = os.environ.get('PKGEXT')

        pkgext = pkgext_env or pkgext_makepkgconf or '.pkg.tar.xz'
        fullpkgnames = []
        fullpkgname_x86_64_tmpl = "{}-{}-x86_64{}"
        fullpkgname_any_tmpl = "{}-{}-any{}"
        if fullpkgname_x86_64_tmpl.format(self.name, self.version_latest,
                                          pkgext) in os.listdir(
                                              self.srcpkg.srcdir):
            fullpkgnames.append(
                fullpkgname_x86_64_tmpl.format(self.name, self.version_latest,
                                               pkgext))
        elif fullpkgname_any_tmpl.format(self.name, self.version_latest,
                                         pkgext) in os.listdir(
                                             self.srcpkg.srcdir):
            fullpkgnames.append(
                fullpkgname_any_tmpl.format(self.name, self.version_latest,
                                            pkgext))
        else:
            fullpkgnames = [
                p for p in os.listdir(self.srcpkg.srcdir) if p.endswith(pkgext)
            ]

        if fullpkgnames:
            for fpn in fullpkgnames:
                self.built_pkgs.append(fpn)
                if os.path.exists(os.path.join(self.ctx.cachedir, fpn)):
                    if not os.path.isfile(os.path.join(self.ctx.cachedir,
                                                       fpn)):
                        utils.logerr(
                            None, 0,
                            "Something (that's not a file) is shadowing package {} in cache directory {}"
                            .format((fpn), self.cachedir))
                else:
                    shutil.move(os.path.join(self.srcpkg.srcdir, fpn),
                                self.ctx.cachedir)
        else:
            utils.logerr(
                None,
                "No package file found in builddir for {}, aborting this subtree"
                .format(self.name))
            return False

        return True
示例#5
0
        def review_file(fname, via=None):
            ref_file = os.path.join(self.ctx.revieweddir, self.name, fname)
            # compare both reference PKGBUILD (if existent) and new PKGBUILD

            refhash = hash_file(ref_file)
            newhash = hash_file(fname)

            if refhash == newhash and not self.ctx.force_review:
                msg = "{} of srcpkg {} passed review: already positively reviewed previously"
                utils.logmsg(self.ctx.v, 0, msg.format(fname, self.name))
                return True
            else:
                # we need review, first diff it if reference exists
                user_verdict = None
                if os.path.exists(ref_file):
                    user_verdict = 'd'  # diff
                else:
                    user_verdict = 'e'  # edit (display with direct editing option)

                while True:
                    if user_verdict == 'p':  # file passed review
                        save_as_reviewed_file(fname)
                        return True
                    elif user_verdict in [
                            'f', 's'
                    ]:  # file failed review or was skipped
                        return False
                    elif user_verdict == 'e':  # user decides to edit
                        subprocess.call(
                            [os.environ.get('EDITOR') or 'nano', fname])
                    elif user_verdict == 'd':  # user decides to diff
                        if os.path.exists(ref_file):

                            termsize = shutil.get_terminal_size()
                            separator_width = termsize.columns - 2  # 1 whitespace padding on each side

                            print()
                            print(
                                colored(' ' + '=' * separator_width,
                                        attrs=['bold']))
                            print()
                            if self.ctx.difftool:
                                try:
                                    subprocess.call(
                                        [self.ctx.difftool, fname, ref_file])
                                except Exception as e:
                                    utils.logerr(
                                        4,
                                        "Error using {} for diff: {}".format(
                                            self.ctx.difftool, e))
                            else:
                                with open(fname, 'r') as f:
                                    max_linelength = max([
                                        len(line) for line in
                                        f.read().strip().split('\n')
                                    ])

                                diffwidth = min(2 * max_linelength,
                                                os.get_terminal_size().columns)
                                diffcmd = [
                                    "colordiff", "--side-by-side",
                                    "--left-column",
                                    "--width={}".format(diffwidth)
                                ]

                                subprocess.call(diffcmd + [fname, ref_file])
                                print()

                                padding = " " * (int(diffwidth / 2) - 9)
                                subscript = "{}new <== | ==> previously positively reviewed".format(
                                    padding)
                                print(colored(subscript, attrs=['bold']))

                        else:
                            utils.logmsg(
                                0, 0,
                                "No reference available, cannot provide diff")

                    if via:
                        # if we get a source pkg calling the review we can deduct
                        # a dependency chain leading to this srcpkg
                        origin = ""
                        if via.name != self.name:
                            # if the SourcePkg and the Package are named identically, hide the SourcePkg-distinction
                            origin += "via " + via.name

                        while via.parents:
                            origin += " → " + via.parents[0].name
                            if len(via.parents) > 1:
                                origin += " (among others)"
                            via = via.parents[0]

                        if origin == "":
                            print("{} of package {}:".format(fname, self.name))
                        else:
                            print("{} of package {} ({}):".format(
                                fname, self.name, origin))
                    else:
                        print("{} of package {}:".format(fname, self.name))

                    user_verdict = utils.getchar(
                        "(P)ass review, (F)ail review, (E)dit, (D)iff, (S)kip?: [p/f/e/d/s] "
                    ).lower()
示例#6
0
    def build(self, buildflags=['-Cdf'], recursive=False):
        if recursive:
            for d in self.deps:
                succeeded = d.build(buildflags=buildflags, recursive=True)
                if not succeeded:
                    return False  # one dep fails, the entire branch fails immediately, software will not be runnable

        if self.in_repos or (self.installed and not self.in_aur):
            return True

        if self.installed and self.in_aur and self.version_installed == self.version_latest and not self.rebuild:
            return True

        pkgs = pkg_in_cache(self)
        if len(pkgs) > 0 and not self.rebuild:
            self.built_pkgs.append(
                pkgs[0]
            )  # we only need one of them, not all, if multiple ones with different extensions have been built
            return True

        utils.logmsg(self.ctx.v, 3, "building sources of {}".format(self.name))
        if self.srcpkg.built:
            return self.srcpkg.build_success

        succeeded = self.srcpkg.build(buildflags=buildflags)
        if not succeeded:
            utils.logerr(
                None,
                "Building sources of package {} failed, aborting this subtree".
                format(self.name))
            return False

        pkgext = os.environ.get('PKGEXT') or 'tar.xz'
        fullpkgnames = []
        fullpkgname_x86_64_tmpl = "{}-{}-x86_64.pkg.{}"
        fullpkgname_any_tmpl = "{}-{}-any.pkg.{}"
        if fullpkgname_x86_64_tmpl.format(self.name, self.version_latest,
                                          pkgext) in os.listdir(
                                              self.srcpkg.srcdir):
            fullpkgnames.append(
                fullpkgname_x86_64_tmpl.format(self.name, self.version_latest,
                                               pkgext))
        elif fullpkgname_any_tmpl.format(self.name, self.version_latest,
                                         pkgext) in os.listdir(
                                             self.srcpkg.srcdir):
            fullpkgnames.append(
                fullpkgname_any_tmpl.format(self.name, self.version_latest,
                                            pkgext))
        else:
            fullpkgnames = [
                p for p in os.listdir(self.srcpkg.srcdir)
                if p.endswith('.pkg.{}'.format(pkgext))
            ]

        if fullpkgnames:
            for fpn in fullpkgnames:
                self.built_pkgs.append(fpn)
                if os.path.exists(os.path.join(self.ctx.cachedir, fpn)):
                    if not os.path.isfile(os.path.join(self.ctx.cachedir,
                                                       fpn)):
                        utils.logerr(
                            None, 0,
                            "Something (that's not a file) is shadowing package {} in cache directory {}"
                            .format((fpn), self.cachedir))
                else:
                    shutil.move(os.path.join(self.srcpkg.srcdir, fpn),
                                self.ctx.cachedir)
        else:
            utils.logerr(
                None,
                "No package file found in builddir for {}, aborting this subtree"
                .format(self.name))
            return False

        return True