summaryrefslogtreecommitdiff
path: root/setup.py
diff options
context:
space:
mode:
Diffstat (limited to 'setup.py')
-rw-r--r--setup.py163
1 files changed, 103 insertions, 60 deletions
diff --git a/setup.py b/setup.py
index a50a0aa..8e334d1 100644
--- a/setup.py
+++ b/setup.py
@@ -23,7 +23,9 @@ to do this step:
It helps to review this auto-generated file on GitHub prior to uploading
because the long description will be sent to PyPI and appear there after
-publishing.
+publishing. PyPI attempts to convert this string to HTML before displaying
+it on the PyPI project page. If PyPI finds any issues, it will render it
+instead as plain-text, which we do not want.
To check in advance that PyPI will accept and parse the reST file as HTML,
you can use the rst2html program installed by the docutils package
@@ -31,8 +33,8 @@ you can use the rst2html program installed by the docutils package
$ pip install docutils
-You will want to issue a command like the following and check that no
-warnings are issued:
+To check the file, run the following command and confirm that it reports
+no warnings:
$ python setup.py --long-description | rst2html.py -v --no-raw > out.html
@@ -40,7 +42,6 @@ See here for more information:
http://docs.python.org/distutils/uploading.html#pypi-package-display
-
(2) Push to PyPI. To release a new version of Pystache to PyPI--
http://pypi.python.org/pypi/pystache
@@ -119,9 +120,9 @@ README_PATH = 'README.md'
HISTORY_PATH = 'HISTORY.md'
LICENSE_PATH = 'LICENSE'
-DESCRIPTION_PATH = 'setup_description.rst'
+RST_DESCRIPTION_PATH = 'setup_description.rst'
-TEMP_REST_EXTENSION = '.temp.rst'
+TEMP_EXTENSION = '.temp'
PREP_COMMAND = 'prep'
@@ -140,6 +141,12 @@ CLASSIFIERS = (
'Programming Language :: Python :: Implementation :: PyPy',
)
+# Comments in reST begin with two dots.
+RST_LONG_DESCRIPTION_INTRO = """\
+.. Do not edit this file. This file is auto-generated for PyPI by setup.py
+.. using pandoc, so edits should go in the source files rather than here.
+"""
+
def read(path):
"""
@@ -162,7 +169,7 @@ def write(u, path):
Write a unicode string to a file (as utf-8).
"""
- print("Writing to: %s" % path)
+ print("writing to: %s" % path)
# This function implementation was chosen to be compatible across Python 2/3.
f = open(path, "wb")
try:
@@ -172,64 +179,125 @@ def write(u, path):
f.close()
-def make_temp_path(path):
+def make_temp_path(path, new_ext=None):
+ """
+ Arguments:
+
+ new_ext: the new file extension, including the leading dot.
+ Defaults to preserving the existing file extension.
+
+ """
root, ext = os.path.splitext(path)
- temp_path = root + TEMP_REST_EXTENSION
+ if new_ext is None:
+ new_ext = ext
+ temp_path = root + TEMP_EXTENSION + new_ext
return temp_path
-def make_description_file(target_path):
+def strip_html_comments(text):
+ """Strip HTML comments from a unicode string."""
+ lines = text.splitlines(True) # preserve line endings.
+
+ # Remove HTML comments (which we only allow to take a special form).
+ new_lines = filter(lambda line: not line.startswith("<!--"), lines)
+
+ return "".join(new_lines)
+
+
+# We write the converted file to a temp file to simplify debugging and
+# to avoid removing a valid pre-existing file on failure.
+def convert_md_to_rst(md_path, rst_temp_path):
"""
- Generate the long_description needed for setup.py.
+ Convert the contents of a file from Markdown to reStructuredText.
+
+ Returns the converted text as a Unicode string.
+
+ Arguments:
- The long description needs to be formatted as reStructuredText:
+ md_path: a path to a UTF-8 encoded Markdown file to convert.
- http://docs.python.org/distutils/setupscript.html#additional-meta-data
+ rst_temp_path: a temporary path to which to write the converted contents.
"""
- # Comments in reST begin with two dots.
- intro = """\
-.. This file is auto-generated by setup.py for PyPI using pandoc, so this
-.. file should not be edited. Edits should go in the source files.
-"""
+ # Pandoc uses the UTF-8 character encoding for both input and output.
+ command = "pandoc --write=rst --output=%s %s" % (rst_temp_path, md_path)
+ print("converting with pandoc: %s to %s\n-->%s" % (md_path, rst_temp_path,
+ command))
+
+ if os.path.exists(rst_temp_path):
+ os.remove(rst_temp_path)
+
+ os.system(command)
+
+ if not os.path.exists(rst_temp_path):
+ s = ("Error running: %s\n"
+ " Did you install pandoc per the %s docstring?" % (command,
+ __file__))
+ sys.exit(s)
+
+ return read(rst_temp_path)
- readme_path = convert_md_to_rst(README_PATH)
- history_path = convert_md_to_rst(HISTORY_PATH)
- license = """\
+# The long_description needs to be formatted as reStructuredText.
+# See the following for more information:
+#
+# http://docs.python.org/distutils/setupscript.html#additional-meta-data
+# http://docs.python.org/distutils/uploading.html#pypi-package-display
+#
+def make_long_description():
+ """
+ Generate the reST long_description for setup() from source files.
+
+ Returns the generated long_description as a unicode string.
+
+ """
+ readme_path = README_PATH
+
+ # Remove our HTML comments because PyPI does not allow it.
+ # See the setup.py docstring for more info on this.
+ readme_md = strip_html_comments(read(readme_path))
+ history_md = strip_html_comments(read(HISTORY_PATH))
+ license_md = """\
License
=======
""" + read(LICENSE_PATH)
- sections = [intro, read(readme_path), read(history_path), license]
+ sections = [readme_md, history_md, license_md]
+ md_description = '\n\n'.join(sections)
+
+ # Write the combined Markdown file to a temp path.
+ md_ext = os.path.splitext(readme_path)[1]
+ md_description_path = make_temp_path(RST_DESCRIPTION_PATH, new_ext=md_ext)
+ write(md_description, md_description_path)
- description = '\n'.join(sections)
+ rst_temp_path = make_temp_path(RST_DESCRIPTION_PATH)
+ long_description = convert_md_to_rst(md_path=md_description_path,
+ rst_temp_path=rst_temp_path)
- write(description, target_path)
+ return "\n".join([RST_LONG_DESCRIPTION_INTRO, long_description])
def prep():
- make_description_file(DESCRIPTION_PATH)
+ """Update the reST long_description file."""
+ long_description = make_long_description()
+ write(long_description, RST_DESCRIPTION_PATH)
-def publish():
- """
- Publish this package to PyPI (aka "the Cheeseshop").
- """
- temp_path = make_temp_path(DESCRIPTION_PATH)
- make_description_file(temp_path)
+def publish():
+ """Publish this package to PyPI (aka "the Cheeseshop")."""
+ long_description = make_long_description()
- if read(temp_path) != read(DESCRIPTION_PATH):
+ if long_description != read(RST_DESCRIPTION_PATH):
print("""\
Description file not up-to-date: %s
Run the following command and commit the changes--
python setup.py %s
-""" % (DESCRIPTION_PATH, PREP_COMMAND))
+""" % (RST_DESCRIPTION_PATH, PREP_COMMAND))
sys.exit()
- print("Description up-to-date: %s" % DESCRIPTION_PATH)
+ print("Description up-to-date: %s" % RST_DESCRIPTION_PATH)
answer = raw_input("Are you sure you want to publish to PyPI (yes/no)?")
@@ -239,31 +307,6 @@ Run the following command and commit the changes--
os.system('python setup.py sdist upload')
-def convert_md_to_rst(path):
- """
- Convert the given file from markdown to reStructuredText.
-
- Returns the new path.
-
- """
- temp_path = make_temp_path(path)
- print("Converting: %s to %s" % (path, temp_path))
-
- if os.path.exists(temp_path):
- os.remove(temp_path)
-
- # Pandoc uses the UTF-8 character encoding for both input and output.
- command = "pandoc --write=rst --output=%s %s" % (temp_path, path)
- os.system(command)
-
- if not os.path.exists(temp_path):
- s = ("Error running: %s\n"
- " Did you install pandoc per the %s docstring?" % (command, __file__))
- sys.exit(s)
-
- return temp_path
-
-
# We use the package simplejson for older Python versions since Python
# does not contain the module json before 2.6:
#
@@ -332,7 +375,7 @@ def main(sys_argv):
prep()
sys.exit()
- long_description = read(DESCRIPTION_PATH)
+ long_description = read(RST_DESCRIPTION_PATH)
template_files = ['*.mustache', '*.txt']
extra_args = get_extra_args()