예제 #1
0
 def _port_ready(self, port):
     """Add a port to the stage queue."""
     assert not self._pending[port]
     assert not self.ports[port].stack.failed
     assert not port.dependency.check(self.stage)
     del self._pending[port]
     stagejob = self.ports[port]
     if self._port_check(port):
         if stagejob.complete():
             stagejob.run()
         else:
             log.debug(
                 "StageBuilder._port_ready()",
                 "Port '%s': queuing job for stage %s" %
                 (port.origin, self.stage.name))
             assert self.stage.prev in port.stages
             self.update.emit(self, Builder.QUEUED, port)
             stagejob.started.connect(self._started)
             self.queue.add(stagejob)
     else:
         if not self.stage.check(port):
             stagejob.run()
         else:
             stagejob.done()
             log.debug(
                 "StageBuilder._port_ready()",
                 "Port '%s': skipping stage %s" %
                 (port.origin, self.stage.name))
예제 #2
0
파일: build.py 프로젝트: repcsi/portbuilder
 def _post_make(self, status):
     """Process the results of make.target()."""
     distfiles = set(self.port.attr["distfiles"])
     self._fetch_lock.release(distfiles)
     if status:
         self._bad_checksum.difference_update(distfiles)
         self._fetched.update(distfiles)
     else:
         files = ", ".join("'%s'" % i for i in distfiles)
         log.debug(
             "Fetch._post_make()",
             "Fetch '%s': failed to fetch distfiles: %s" %
             (self.port.origin, files))
         self._bad_checksum.update(distfiles)
         self._fetch_failed.update(distfiles)
     # TODO:
     # - extend queue to handle non-active "done" jobs
     # - make queue finish via signal, not direct call to queue.done
     # ? track which jobs are handling which distfiles (cleanup with done())
     # Go through all the pending fetch jobs and see if any have been
     # resolved due to this job:
     for q in (queue.fetch.stalled, queue.fetch.queue):
         for i in range(len(q) - 1, -1, -1):
             j = q[i]
             if (isinstance(j, Fetch)
                     and not distfiles.isdisjoint(j.port.attr["distfiles"])
                     and (not j.check(j.port) or j.complete())):
                 del q[i]
                 j.run()
     return status
예제 #3
0
 def _post_make(self, status):
     """Process the results of make.target()."""
     distfiles = set(self.port.attr["distfiles"])
     self._fetch_lock.release(distfiles)
     if status:
         self._bad_checksum.difference_update(distfiles)
         self._fetched.update(distfiles)
     else:
         files = ", ".join("'%s'" % i for i in distfiles)
         log.debug("Fetch._post_make()",
                   "Fetch '%s': failed to fetch distfiles: %s" %
                       (self.port.origin, files))
         self._bad_checksum.update(distfiles)
         self._fetch_failed.update(distfiles)
     # TODO:
     # - extend queue to handle non-active "done" jobs
     # - make queue finish via signal, not direct call to queue.done
     # ? track which jobs are handling which distfiles (cleanup with done())
     # Go through all the pending fetch jobs and see if any have been
     # resolved due to this job:
     for q in (queue.fetch.stalled, queue.fetch.queue):
         for i in range(len(q) - 1, -1, -1):
             j = q[i]
             if (isinstance(j, Fetch) and
                     not distfiles.isdisjoint(j.port.attr["distfiles"]) and
                     (not j.check(j.port) or j.complete())):
                 del q[i]
                 j.run()
     return status
예제 #4
0
 def _port_ready(self, port):
     """Add a port to the stage queue."""
     assert not self._pending[port]
     assert not self.ports[port].stack.failed
     assert not port.dependency.check(self.stage)
     del self._pending[port]
     stagejob = self.ports[port]
     if self._port_check(port):
         if stagejob.complete():
             stagejob.run()
         else:
             log.debug("StageBuilder._port_ready()",
                     "Port '%s': queuing job for stage %s" %
                         (port.origin, self.stage.name))
             assert self.stage.prev in port.stages
             self.update.emit(self, Builder.QUEUED, port)
             stagejob.started.connect(self._started)
             self.queue.add(stagejob)
     else:
         if not self.stage.check(port):
             stagejob.run()
         else:
             stagejob.done()
             log.debug("StageBuilder._port_ready()",
                     "Port '%s': skipping stage %s" %
                         (port.origin, self.stage.name))
예제 #5
0
    def _add(self, port, pending=0):
        """Add a ports dependencies and prior stage to be built."""
        from .env import flags

        # Don't try and build a port that has already failed
        # or cannot be built
        if port.failed or port.dependency.failed:
            self.ports[port].stage_done()
            return

        depends = port.dependency.check(self.stage)

        # Add all outstanding ports to be installed
        self._pending[port] = len(depends) + pending
        for p in depends:
            if p not in self._depends:
                self._depends[p] = set()
                depend_resolve(p).connect(self._depend_resolv)
            self._depends[p].add(port)

        # Build the previous stage if needed
        if (self.prev_builder and (port.install_status <= flags["stage"] or
                                   port.force) and port.stage < self.stage - 1):
            self._pending[port] += 1
            self.prev_builder.add(port).connect(self._stage_resolv)

        log.debug("StageBuilder._add()",
                  "Port '%s': added job for stage %d, waiting on %d" %
                      (port.origin, self.stage, self._pending[port]))

        # Build stage if port is ready
        if not self._pending[port]:
            self._port_ready(port)
예제 #6
0
파일: mk.py 프로젝트: DragonSA/portbuilder
def attr(origin):
    """Retrieve a ports attributes by using the attribute queue."""
    # TODO inline function to caller
    log.debug("attr()", "Port '%s': getting attribute" % origin)
    attr_obj = Attr(origin)
    queue.attr.add(job.AttrJob(attr_obj))
    return attr_obj
예제 #7
0
 def clean(self, force=False):
     """Remove port's working director and log files."""
     if stacks.Build in self.stages or force:
         mak = make.make_target(self, "clean", NOCLEANDEPENDS=True)
         log.debug("Port.clean()", "Port '%s': full clean" % self.origin)
         return mak.connect(self._post_clean)
     else:
         self._post_clean()
         log.debug("Port.clean()", "Port '%s': quick clean" % self.origin)
         return True
예제 #8
0
파일: port.py 프로젝트: repcsi/portbuilder
 def clean(self, force=False):
     """Remove port's working director and log files."""
     if stacks.Build in self.stages or force:
         mak = make.make_target(self, "clean", NOCLEANDEPENDS=True)
         log.debug("Port.clean()", "Port '%s': full clean" % self.origin)
         return mak.connect(self._post_clean)
     else:
         self._post_clean()
         log.debug("Port.clean()", "Port '%s': quick clean" % self.origin)
         return True
예제 #9
0
 def _depend_resolv(self, depend):
     """Update dependency structures for resolved dependency."""
     if not self._port_failed(depend):
         all_depends = ["'%s'" % i.origin for i in self._depends[depend]]
         log.debug("StageBuilder._depend_resolv()",
                   "Port '%s': resolved stage %d for ports %s" %
                       (depend.origin, self.stage, ", ".join(all_depends)))
         for port in self._depends.pop(depend):
             if not self._port_failed(port):
                 self._pending[port] -= 1
                 if not self._pending[port]:
                     self._port_ready(port)
예제 #10
0
    def _do_stage(self):  # pylint: disable-msg=E0202
        """Issue a pkg.add() to install the package from a repo."""
        log.debug(
            "PackageInstaller._do_stage()",
            "Port '%s': building stage %s" % (self.port.origin, self.name))

        pkg_add = self._add_pkg()
        # pkg_add may be False if installing `ports-mgmt/pkg` and
        # env.flags["pkg_mgmt"] == "pkgng"
        if pkg_add:
            self.pid = pkg_add.connect(self._post_pkg_add).pid
        else:
            # Cannot call self._finalise from within self.work() ->
            #   self._do_stage()
            event.post_event(self._finalise, False)
예제 #11
0
    def _do_stage(self):  # pylint: disable-msg=E0202
        """Issue a pkg.add() to install the package from a repo."""
        log.debug("PackageInstaller._do_stage()",
                  "Port '%s': building stage %s" %
                      (self.port.origin, self.name))


        pkg_add = self._add_pkg()
        # pkg_add may be False if installing `ports-mgmt/pkg` and
        # env.flags["pkg_mgmt"] == "pkgng"
        if pkg_add:
            self.pid = pkg_add.connect(self._post_pkg_add).pid
        else:
            # Cannot call self._finalise from within self.work() ->
            #   self._do_stage()
            event.post_event(self._finalise, False)
예제 #12
0
 def _finalise(self, status):
     """Finalise the stage."""
     if not status:
         log.error("Stage._finalise()", "Port '%s': failed stage %s" %
                       (self.port.origin, self.name))
         if self.stack.name == "common":
             for stack in self.port.stacks.values():
                 stack.failed = self.__class__
         else:
             self.stack.failed = self.__class__
         self.failed = True
     else:
         log.debug("Stage._finalise()", "Port '%s': finished stage %s" %
                       (self.port.origin, self.name))
     self.stack.working = False
     self.port.stages.add(self.__class__)
     self.done()
예제 #13
0
 def _post_pkg_add(self, pkg_add):
     """Process the results of pkg.add()."""
     self.pid = None
     if pkg_add.wait() == make.SUCCESS:
         log.debug("PackageInstaller._post_pkg_add()",
                  "Port '%s': finished stage %s" %
                     (self.port.origin, self.name))
         if "explicit" not in self.port.flags:
             pkg_change = self.pid = pkg.change(self.port, "explicit", False)
             if pkg_change:
                 self.pid = pkg_change.connect(self._post_pkg_change).pid
                 return
         self._finalise(True)
     else:
         log.error("PackageInstaller._port_pkg_add()",
                   "Port '%s': failed stage %s" %
                     (self.port.origin, self.name))
         self._finalise(False)
예제 #14
0
 def _depend_resolv(self, port):
     """Update dependency structures for resolved dependency."""
     if not port.dependent.failed and env.flags["mode"] != "clean":
         all_depends = ["'%s'" % i.origin for i in self._depends[port]]
         resolved_ports = ", ".join(all_depends)
         log.debug("StageBuilder._depend_resolv()",
                   "Port '%s': resolved stage %s for ports %s" %
                       (port.origin, self.stage.name, resolved_ports))
     for port in self._depends.pop(port):
         if port not in self.failed:
             if not port.dependency.failed and env.flags["mode"] != "clean":
                 self._pending[port] -= 1
                 if not self._pending[port]:
                     self._port_ready(port)
             else:
                 if not self.ports[port].stack.failed:
                     self.ports[port].stack.failed = True
                 self._port_failed(port)
예제 #15
0
 def _port_ready(self, port):
     """Add a port to the stage queue."""
     assert not self._pending[port]
     assert not port.failed or port.dependency.fail
     assert not port.dependency.check(self.stage)
     del self._pending[port]
     if self._port_check(port):
         log.debug("StageBuilder._port_ready()",
                   "Port '%s': queuing job for stage %d" %
                       (port.origin, self.stage))
         assert port.stage == self.stage - 1 or self.stage > Port.PACKAGE
         self.update.emit(self, Builder.QUEUED, port)
         self.ports[port].started.connect(self._started)
         self.queue.add(self.ports[port])
     else:
         log.debug("StageBuilder._port_ready()",
                   "Port '%s': skipping stage %d" %
                       (port.origin, self.stage))
예제 #16
0
 def _depend_resolv(self, port):
     """Update dependency structures for resolved dependency."""
     if not port.dependent.failed and env.flags["mode"] != "clean":
         all_depends = ["'%s'" % i.origin for i in self._depends[port]]
         resolved_ports = ", ".join(all_depends)
         log.debug(
             "StageBuilder._depend_resolv()",
             "Port '%s': resolved stage %s for ports %s" %
             (port.origin, self.stage.name, resolved_ports))
     for port in self._depends.pop(port):
         if port not in self.failed:
             if not port.dependency.failed and env.flags["mode"] != "clean":
                 self._pending[port] -= 1
                 if not self._pending[port]:
                     self._port_ready(port)
             else:
                 if not self.ports[port].stack.failed:
                     self.ports[port].stack.failed = True
                 self._port_failed(port)
예제 #17
0
파일: base.py 프로젝트: repcsi/portbuilder
 def _finalise(self, status):
     """Finalise the stage."""
     if not status:
         log.error(
             "Stage._finalise()",
             "Port '%s': failed stage %s" % (self.port.origin, self.name))
         if self.stack.name == "common":
             for stack in self.port.stacks.values():
                 stack.failed = self.__class__
         else:
             self.stack.failed = self.__class__
         self.failed = True
     else:
         log.debug(
             "Stage._finalise()",
             "Port '%s': finished stage %s" % (self.port.origin, self.name))
     self.stack.working = False
     self.port.stages.add(self.__class__)
     self.done()
예제 #18
0
 def _post_pkg_add(self, pkg_add):
     """Process the results of pkg.add()."""
     self.pid = None
     if pkg_add.wait() == make.SUCCESS:
         log.debug(
             "PackageInstaller._post_pkg_add()",
             "Port '%s': finished stage %s" % (self.port.origin, self.name))
         if "explicit" not in self.port.flags:
             pkg_change = self.pid = pkg.change(self.port, "explicit",
                                                False)
             if pkg_change:
                 self.pid = pkg_change.connect(self._post_pkg_change).pid
                 return
         self._finalise(True)
     else:
         log.error(
             "PackageInstaller._port_pkg_add()",
             "Port '%s': failed stage %s" % (self.port.origin, self.name))
         self._finalise(False)
예제 #19
0
    def work(self):
        assert not self.stack.working
        assert not self.failed

        log.debug("Stage.work()", "Port '%s': starting stage %s" %
                      (self.port.origin, self.name))
        if not self.check(self.port):
            # Cannot call self._finalise(True) directly as self.done() cannot
            # be called from within the scope of self.work()
            event.post_event(self._finalise, False)
            return
        assert self.prev in self.port.stages
        assert (not self.port.dependency or
                not self.port.dependency.check(self.__class__))
        if self.complete():
            # Cannot call self._finalise(True) directly as self.done() cannot
            # be called from within the scope of self.work()
            event.post_event(self._finalise, True)
        else:
            self._do_stage()  # May throw job.JobStalled()
            self.stack.working = time.time()
예제 #20
0
    def _cleanup(self, stagejob):
        """Cleanup after the port has completed its stage."""
        port = stagejob.port
        log.debug("StageBuilder._cleanup()",
                  "Port '%s': completed job for stage %s" %
                      (stagejob.port.origin, self.stage.name))

        failed = stagejob.stack.failed or env.flags["mode"] == "clean"
        del self.ports[port]
        if port in self.cleanup and not env.flags["mode"] == "clean":
            self.cleanup.remove(port)
            if not failed:
                self.done.append(port)
                self.update.emit(self, Builder.DONE, port)
            if env.flags["target"][-1] == "clean":
                queue.clean.add(job.CleanJob(port))
        elif not failed:
            self.succeeded.append(port)
            self.update.emit(self, Builder.SUCCEEDED, port)
        if failed:
            self.update.emit(self, Builder.FAILED, port)
예제 #21
0
 def _find_method(self, port):
     """Find a method to resolve the port."""
     while True:
         method = self.method[port]
         if not method:
             # No method left, port failed to resolve
             del self.method[port]
             for stack in port.stacks.values():
                 if stack.failed and stack.failed is not True:
                     port.flags.add("failed")
                     break
             port.dependent.status_changed(exhausted=True)
             if port.dependent.failed and not port.dependency.failed:
                 log.debug("DependLoader._find_method()",
                           "Port '%s': no viable resolve method found" %
                              (port.origin,))
             return False
         else:
             self.method[port] = self._next(self.method[port])
             if self._resolve(port, method):
                 log.debug("DependLoader._find_method()",
                           "Port '%s': resolving using method '%s'" %
                               (port.origin, method))
                 return True
             else:
                 log.debug("DependLoader._find_method()",
                           "Port '%s': skipping resolve method '%s'" %
                               (port.origin, method))
예제 #22
0
 def _find_method(self, port):
     """Find a method to resolve the port."""
     while True:
         method = self.method[port]
         if not method:
             # No method left, port failed to resolve
             del self.method[port]
             for stack in port.stacks.values():
                 if stack.failed and stack.failed is not True:
                     port.flags.add("failed")
                     break
             port.dependent.status_changed(exhausted=True)
             if port.dependent.failed and not port.dependency.failed:
                 log.debug(
                     "DependLoader._find_method()",
                     "Port '%s': no viable resolve method found" %
                     (port.origin, ))
             return False
         else:
             self.method[port] = self._next(self.method[port])
             if self._resolve(port, method):
                 log.debug(
                     "DependLoader._find_method()",
                     "Port '%s': resolving using method '%s'" %
                     (port.origin, method))
                 return True
             else:
                 log.debug(
                     "DependLoader._find_method()",
                     "Port '%s': skipping resolve method '%s'" %
                     (port.origin, method))
예제 #23
0
    def _cleanup(self, stagejob):
        """Cleanup after the port has completed its stage."""
        port = stagejob.port
        log.debug(
            "StageBuilder._cleanup()",
            "Port '%s': completed job for stage %s" %
            (stagejob.port.origin, self.stage.name))

        failed = stagejob.stack.failed or env.flags["mode"] == "clean"
        del self.ports[port]
        if port in self.cleanup and not env.flags["mode"] == "clean":
            self.cleanup.remove(port)
            if not failed:
                self.done.append(port)
                self.update.emit(self, Builder.DONE, port)
            if env.flags["target"][-1] == "clean":
                queue.clean.add(job.CleanJob(port))
        elif not failed:
            self.succeeded.append(port)
            self.update.emit(self, Builder.SUCCEEDED, port)
        if failed:
            self.update.emit(self, Builder.FAILED, port)
예제 #24
0
파일: base.py 프로젝트: repcsi/portbuilder
    def work(self):
        assert not self.stack.working
        assert not self.failed

        log.debug(
            "Stage.work()",
            "Port '%s': starting stage %s" % (self.port.origin, self.name))
        if not self.check(self.port):
            # Cannot call self._finalise(True) directly as self.done() cannot
            # be called from within the scope of self.work()
            event.post_event(self._finalise, False)
            return
        assert self.prev in self.port.stages
        assert (not self.port.dependency
                or not self.port.dependency.check(self.__class__))
        if self.complete():
            # Cannot call self._finalise(True) directly as self.done() cannot
            # be called from within the scope of self.work()
            event.post_event(self._finalise, True)
        else:
            self._do_stage()  # May throw job.JobStalled()
            self.stack.working = time.time()
예제 #25
0
    def _cleanup(self, job):
        """Cleanup after the port has completed its stage."""
        from .env import flags

        log.debug("StageBuilder._cleanup()",
                  "Port '%s': completed job for stage %d" %
                      (job.port.origin, self.stage))

        del self.ports[job.port]
        failed = self._port_failed(job.port)
        if job.port in self.cleanup and not flags["mode"] == "clean":
            self.cleanup.remove(job.port)
            if not failed:
                self.done.append(job.port)
                self.update.emit(self, Builder.DONE, job.port)
            if env.flags["target"][-1] == "clean":
                queue.clean.add(CleanJob(job.port))
        elif not failed:
            self.succeeded.append(job.port)
            self.update.emit(self, Builder.SUCCEEDED, job.port)
        if failed:
            self.update.emit(self, Builder.FAILED, job.port)
예제 #26
0
 def _find_method(self, port):
     """Find a method to resolve the port."""
     while True:
         method = self.method[port]
         if not method:
             # No method left, port failed to resolve
             del self.method[port]
             port.failed = True
             port.dependent.status_changed()
             log.debug("DependLoader._find_method()",
                       "Port '%s': no viable resolve method found" % (port,))
             return False
         else:
             self.method[port] = self._next(self.method[port])
             port.dependent.propogate = not self.method[port]
             if self._resolve(port, method):
                 log.debug("DependLoader._find_method()",
                           "Port '%s': resolving using method '%s'" %
                               (port, method))
                 return True
             else:
                 log.debug("DependLoader._find_method()",
                           "Port '%s': skipping resolve method '%s'" %
                               (port, method))