Commits

Sebastian Wiesner  committed f755582

Added cwd option to set the working directory of commands, fixes #28

Working directory now defaults to the top level source directory instead of the
working directory of the "sphinx-build" process.

  • Participants
  • Parent commits f3128b1

Comments (0)

Files changed (3)

File programoutput/CHANGES.rst

 
 - Python 3 support
 - Require Sphinx 1.1 now
+- #28: Added ``cwd`` option to :rst:dir:`program-output`
+- #28: Working directory of executed programs defaults to documentation root
+  now
 
 
 0.5 (Sep 19, 2011)

File programoutput/doc/index.rst

 You can omit the content of the standard error stream with the ``nostderr``
 option.
 
+By default, commands are executed in the top-level source directory.  You can
+choose an alternate working directory with the ``cwd`` option.  The argument of
+this option is either a path relative to the current source file, or a absolute
+path which means that it is relative to the top level source directory.
+
 
 Shortening the output
 ^^^^^^^^^^^^^^^^^^^^^
    literally passed to the system shell.  With the ``nostderr`` option,
    standard error is hidden from the output.
 
+   The working directory of the command can be configured with the ``cwd``
+   option.  The argument of this option is a directory path, relative to the
+   current source file.  Absolute paths are interpreted as relative to the
+   root of the source directory.  The default working directory is ``/``, i.e.
+   the root of the source directory.
+
    If the ``prompt`` option is given, the ``command`` itself is included in the
    document, so that the output mimics input in a shell prompt.
    :confval:`programoutput_prompt_template` controlls the appearance of this.

File programoutput/sphinxcontrib/programoutput.py

 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 # POSSIBILITY OF SUCH DAMAGE.
 
-
 """
     sphinxcontrib.programoutput
     ===========================
 
     option_spec = dict(shell=flag, prompt=flag, nostderr=flag,
                        ellipsis=_slice, extraargs=unchanged,
-                       returncode=nonnegative_int)
+                       returncode=nonnegative_int, cwd=unchanged)
 
     def run(self):
+        env = self.state.document.settings.env
+
         node = program_output()
         node.line = self.lineno
         node['command'] = self.arguments[0]
 
         node['hide_standard_error'] = 'nostderr' in self.options
         node['extraargs'] = self.options.get('extraargs', '')
+        _, cwd = env.relfn2path(self.options.get('cwd', '/'))
+        node['working_directory'] = cwd
         node['use_shell'] = 'shell' in self.options
         node['returncode'] = self.options.get('returncode', 0)
         if 'ellipsis' in self.options:
         return [node]
 
 
-_Command = namedtuple('Command', 'command shell hide_standard_error')
+_Command = namedtuple(
+    'Command', 'command shell hide_standard_error working_directory')
 
 
 class Command(_Command):
     A command to be executed.
     """
 
-    def __new__(cls, command, shell=False, hide_standard_error=False):
+    def __new__(cls, command, shell=False, hide_standard_error=False,
+                working_directory='/'):
         if isinstance(command, list):
             command = tuple(command)
-        return _Command.__new__(cls, command, shell, hide_standard_error)
+        return _Command.__new__(cls, command, shell, hide_standard_error,
+                                working_directory)
 
     @classmethod
     def from_program_output_node(cls, node):
         """
         extraargs = node.get('extraargs', '')
         command = (node['command'] + ' ' + extraargs).strip()
-        return cls(command, node['use_shell'], node['hide_standard_error'])
+        return cls(command, node['use_shell'],
+                   node['hide_standard_error'], node['working_directory'])
 
     def execute(self):
         """
         Return the :class:`~subprocess.Popen` object representing the running
         command.
         """
-        # pylint: disable=E1101
         if self.shell:
             if sys.version_info[0] < 3 and isinstance(self.command, unicode):
                 command = self.command.encode(sys.getfilesystemencoding())
             else:
                 command = self.command
         return Popen(command, shell=self.shell, stdout=PIPE,
-                     stderr=PIPE if self.hide_standard_error else STDOUT)
+                     stderr=PIPE if self.hide_standard_error else STDOUT,
+                     cwd=self.working_directory)
 
     def get_output(self):
         """
         return process.returncode, output
 
     def __str__(self):
-        # pylint: disable=E1101
         if isinstance(self.command, tuple):
             return repr(list(self.command))
         return repr(self.command)