diff --git a/sphinx/cmdline.py b/sphinx/cmdline.py index aee75418c..43c33378c 100644 --- a/sphinx/cmdline.py +++ b/sphinx/cmdline.py @@ -22,17 +22,10 @@ from sphinx.errors import SphinxError from sphinx.application import Sphinx from sphinx.util import Tee, format_exception_cut_frames, save_traceback from sphinx.util.console import red, nocolor, color_terminal -from sphinx.util.osutil import fs_encoding +from sphinx.util.osutil import abspath from sphinx.util.pycompat import terminal_safe, bytes -def abspath(pathdir): - pathdir = path.abspath(pathdir) - if isinstance(pathdir, bytes): - pathdir = pathdir.decode(fs_encoding) - return pathdir - - def usage(argv, msg=None): if msg: print >>sys.stderr, msg diff --git a/sphinx/setup_command.py b/sphinx/setup_command.py index 70358bbbc..07cd520c3 100644 --- a/sphinx/setup_command.py +++ b/sphinx/setup_command.py @@ -19,6 +19,7 @@ from distutils.cmd import Command from sphinx.application import Sphinx from sphinx.util.console import darkred, nocolor, color_terminal +from sphinx.util.osutil import abspath class BuildDoc(Command): @@ -104,14 +105,16 @@ class BuildDoc(Command): self.ensure_dirname('source_dir') if self.source_dir is None: self.source_dir = os.curdir - self.source_dir = os.path.abspath(self.source_dir) + self.source_dir = abspath(self.source_dir) if self.config_dir is None: self.config_dir = self.source_dir + self.config_dir = abspath(self.config_dir) if self.build_dir is None: build = self.get_finalized_command('build') - self.build_dir = os.path.join(build.build_base, 'sphinx') + self.build_dir = os.path.join(abspath(build.build_base), 'sphinx') self.mkpath(self.build_dir) + self.build_dir = abspath(self.build_dir) self.doctree_dir = os.path.join(self.build_dir, 'doctrees') self.mkpath(self.doctree_dir) self.builder_target_dir = os.path.join(self.build_dir, self.builder) diff --git a/sphinx/util/__init__.py b/sphinx/util/__init__.py index 17371ea89..2ff2bff24 100644 --- a/sphinx/util/__init__.py +++ b/sphinx/util/__init__.py @@ -54,7 +54,8 @@ def docname_join(basedocname, docname): def path_stabilize(filepath): "normalize path separater and unicode string" newpath = filepath.replace(os.path.sep, SEP) - newpath = unicodedata.normalize('NFC', newpath) + if isinstance(newpath, unicode): + newpath = unicodedata.normalize('NFC', newpath) return newpath diff --git a/sphinx/util/osutil.py b/sphinx/util/osutil.py index f3557c3ea..f37c10222 100644 --- a/sphinx/util/osutil.py +++ b/sphinx/util/osutil.py @@ -176,3 +176,16 @@ def find_catalog_files(docname, srcdir, locale_dirs, lang, compaction): fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() + + +if sys.version_info < (3, 0): + bytes = str +else: + bytes = bytes + + +def abspath(pathdir): + pathdir = path.abspath(pathdir) + if isinstance(pathdir, bytes): + pathdir = pathdir.decode(fs_encoding) + return pathdir diff --git a/tests/roots/test-setup/doc/conf.py b/tests/roots/test-setup/doc/conf.py new file mode 100644 index 000000000..a55679a4b --- /dev/null +++ b/tests/roots/test-setup/doc/conf.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +project = 'Sphinx smallest project' +source_suffix = '.txt' +keep_warnings = True diff --git a/tests/roots/test-setup/doc/contents.txt b/tests/roots/test-setup/doc/contents.txt new file mode 100644 index 000000000..cb52405ff --- /dev/null +++ b/tests/roots/test-setup/doc/contents.txt @@ -0,0 +1,5 @@ +contents +========= + +spam egg ham + diff --git a/tests/roots/test-setup/setup.cfg b/tests/roots/test-setup/setup.cfg new file mode 100644 index 000000000..cf2a7f56f --- /dev/null +++ b/tests/roots/test-setup/setup.cfg @@ -0,0 +1,5 @@ +[build_sphinx] +project = 'My project' +version = 1.2 +release = 1.2.0 +source-dir = doc diff --git a/tests/roots/test-setup/setup.py b/tests/roots/test-setup/setup.py new file mode 100644 index 000000000..3ba5b6f05 --- /dev/null +++ b/tests/roots/test-setup/setup.py @@ -0,0 +1,9 @@ +from distutils.core import setup +from sphinx.setup_command import BuildDoc + +cmdclass = {'build_sphinx': BuildDoc} + +setup( + name='sphinxdoc', + cmdclass=cmdclass, +) diff --git a/tests/test_setup_command.py b/tests/test_setup_command.py new file mode 100644 index 000000000..23b2b4b79 --- /dev/null +++ b/tests/test_setup_command.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +""" + test_setup_command + ~~~~~~~~~~~~~~~~~~~ + + Test setup_command for distutils. + + :copyright: Copyright 2007-2013 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" + +import os +import sys +import subprocess +from functools import wraps +import tempfile + +from util import with_tempdir, test_roots +from path import path +from textwrap import dedent + +root = test_roots / 'test-setup' + + +def with_setup_command(root, *args, **kwds): + """ + Run `setup.py build_sphinx` with args and kwargs, + pass it to the test and clean up properly. + """ + def generator(func): + @wraps(func) + def deco(*args2, **kwargs2): + tempdir = path(tempfile.mkdtemp()) + pkgrootdir = (tempdir / 'root') + root.copytree(pkgrootdir) + cwd = os.getcwd() + os.chdir(pkgrootdir) + command = [sys.executable, 'setup.py', 'build_sphinx'] + command.extend(args) + try: + proc = subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + func(pkgrootdir, proc, *args, **kwds) + finally: + tempdir.rmtree() + os.chdir(cwd) + return deco + return generator + + +@with_setup_command(root) +def test_build_sphinx(pkgroot, proc): + out, err = proc.communicate() + print(out) + print(err) + assert proc.returncode == 0 + + +@with_setup_command(root) +def test_build_sphinx_with_multibyte_path(pkgroot, proc): + mb_name = u'\u65e5\u672c\u8a9e' + srcdir = (pkgroot / 'doc') + (srcdir / mb_name).makedirs() + (srcdir / mb_name / (mb_name + '.txt')).write_text(dedent(""" + multi byte file name page + ========================== + """)) + + master_doc = srcdir / 'contents.txt' + master_doc.write_bytes((master_doc.text() + dedent(""" + .. toctree:: + + %(mb_name)s/%(mb_name)s + """ % locals()) + ).encode('utf-8')) + + out, err = proc.communicate() + print(out) + print(err) + assert proc.returncode == 0