Mercurial > piecrust2
diff piecrust/publishing/shell.py @ 885:13e8b50a2113
publish: Fix publishers API and add a simple "copy" publisher.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 20 Jun 2017 21:12:35 -0700 |
parents | 42da89d8bd51 |
children | 8ca228956cc6 |
line wrap: on
line diff
--- a/piecrust/publishing/shell.py Tue Jun 20 21:10:39 2017 -0700 +++ b/piecrust/publishing/shell.py Tue Jun 20 21:12:35 2017 -0700 @@ -1,5 +1,71 @@ +import os.path import shlex -from piecrust.publishing.base import ShellCommandPublisherBase +import logging +import threading +import subprocess +from piecrust.publishing.base import Publisher + + +logger = logging.getLogger(__name__) + + +class ShellCommandPublisherBase(Publisher): + def __init__(self, app, target, config): + super(ShellCommandPublisherBase, self).__init__(app, target, config) + self.expand_user_args = True + + def run(self, ctx): + args = self._getCommandArgs(ctx) + if self.expand_user_args: + args = [os.path.expanduser(i) for i in args] + + if ctx.preview: + preview_args = ' '.join([shlex.quote(i) for i in args]) + logger.info( + "Would run shell command: %s" % preview_args) + return True + + logger.debug( + "Running shell command: %s" % args) + + proc = subprocess.Popen( + args, cwd=self.app.root_dir, bufsize=0, + stdout=subprocess.PIPE) + + logger.debug("Running publishing monitor for PID %d" % proc.pid) + thread = _PublishThread(proc) + thread.start() + proc.wait() + thread.join() + + if proc.returncode != 0: + logger.error( + "Publish process returned code %d" % proc.returncode) + else: + logger.debug("Publish process returned successfully.") + + return proc.returncode == 0 + + def _getCommandArgs(self, ctx): + raise NotImplementedError() + + +class _PublishThread(threading.Thread): + def __init__(self, proc): + super(_PublishThread, self).__init__( + name='publish_monitor', daemon=True) + self.proc = proc + self.root_logger = logging.getLogger() + + def run(self): + for line in iter(self.proc.stdout.readline, b''): + line_str = line.decode('utf8') + logger.info(line_str.rstrip('\r\n')) + for h in self.root_logger.handlers: + h.flush() + + self.proc.communicate() + logger.debug("Publish monitor exiting.") class ShellCommandPublisher(ShellCommandPublisherBase):