diff options
| author | tarek <none@none> | 2009-10-09 12:45:58 +0200 |
|---|---|---|
| committer | tarek <none@none> | 2009-10-09 12:45:58 +0200 |
| commit | bee78e98939ba745074de8d9420f22d299dc1a7a (patch) | |
| tree | 09bce5f6f1ae575b1dfca696dce8036f45ef7a83 | |
| parent | 5109e586c2ec65ba97803ebc171609e4c2243974 (diff) | |
| parent | dcc66e813d10098aa88eaa3be169cbc2e8b301b6 (diff) | |
| download | python-setuptools-git-bee78e98939ba745074de8d9420f22d299dc1a7a.tar.gz | |
merge dance
--HG--
branch : distribute
extra : rebase_source : 35e424deb7b3bef880c53fa50dbe079f18076e67
| -rw-r--r-- | CHANGES.txt | 4 | ||||
| -rw-r--r-- | CONTRIBUTORS.txt | 1 | ||||
| -rwxr-xr-x | README.txt | 8 | ||||
| -rw-r--r-- | distribute.egg-info/entry_points.txt | 1 | ||||
| -rw-r--r-- | docs/_theme/nature/static/nature.css_t | 230 | ||||
| -rw-r--r-- | docs/_theme/nature/static/pygments.css | 54 | ||||
| -rw-r--r-- | docs/_theme/nature/theme.conf | 4 | ||||
| -rw-r--r-- | docs/conf.py | 51 | ||||
| -rw-r--r-- | docs/easy_install.txt | 28 | ||||
| -rw-r--r-- | docs/python3.txt | 68 | ||||
| -rw-r--r-- | docs/setuptools.txt | 75 | ||||
| -rwxr-xr-x | setup.cfg | 8 | ||||
| -rwxr-xr-x | setup.py | 1 | ||||
| -rw-r--r-- | setuptools/command/__init__.py | 2 | ||||
| -rw-r--r-- | setuptools/command/upload_docs.py | 153 |
15 files changed, 615 insertions, 73 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index af020552..6685a0e4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -6,8 +6,10 @@ CHANGES 0.6.4 ----- -* Added the generation of distribute_setup_3k.py during the release. +* Added the generation of `distribute_setup_3k.py` during the release. +* Added an upload_docs command to easily upload project documentation to + PyPI's http://packages.python.org. ----- 0.6.3 diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index c4a84b70..5dcc3675 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -4,6 +4,7 @@ Contributors * Alex Grönholm * Hanno Schlichting +* Jannis Leidel * Lennart Regebro * Martin von Loewis * Philip Envey @@ -80,14 +80,14 @@ distribute_setup.py Download ``distribute_setup.py`` and execute it, using the Python interpreter of your choice. -If your shell has the ``wget`` program you can do:: +If your shell has the ``curl`` program you can do:: - $ wget http://nightly.ziade.org/distribute_setup.py + $ curl -O http://nightly.ziade.org/distribute_setup.py $ python distribute_setup.py If you are under Python 3, use ``distribute_setup_3k.py``:: - $ wget http://nightly.ziade.org/distribute_setup_3k.py + $ curl -O http://nightly.ziade.org/distribute_setup_3k.py $ python distribute_setup_3k.py Notice that both files are provided in the source release. @@ -105,7 +105,7 @@ Source installation Download the source tarball, uncompress it, then run the install command:: - $ wget http://pypi.python.org/packages/source/d/distribute/distribute-0.6.4.tar.gz + $ curl -O http://pypi.python.org/packages/source/d/distribute/distribute-0.6.4.tar.gz $ tar -xzvf distribute-0.6.4.tar.gz $ cd distribute-0.6 $ python setup.py install diff --git a/distribute.egg-info/entry_points.txt b/distribute.egg-info/entry_points.txt index d18df338..f4b74da0 100644 --- a/distribute.egg-info/entry_points.txt +++ b/distribute.egg-info/entry_points.txt @@ -7,6 +7,7 @@ build_py = setuptools.command.build_py:build_py saveopts = setuptools.command.saveopts:saveopts egg_info = setuptools.command.egg_info:egg_info register = setuptools.command.register:register +upload_docs = setuptools.command.upload_docs:upload_docs install_egg_info = setuptools.command.install_egg_info:install_egg_info alias = setuptools.command.alias:alias easy_install = setuptools.command.easy_install:easy_install diff --git a/docs/_theme/nature/static/nature.css_t b/docs/_theme/nature/static/nature.css_t new file mode 100644 index 00000000..a29848e1 --- /dev/null +++ b/docs/_theme/nature/static/nature.css_t @@ -0,0 +1,230 @@ +/** + * Sphinx stylesheet -- default theme + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: Arial, sans-serif; + font-size: 100%; + background-color: #111; + color: #555; + margin: 0; + padding: 0; +} + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 300px; +} + +hr{ + border: 1px solid #B1B4B6; +} + +div.document { + background-color: #eee; +} + +div.body { + background-color: #ffffff; + color: #3E4349; + padding: 0 30px 30px 30px; + font-size: 0.8em; +} + +div.footer { + color: #555; + width: 100%; + padding: 13px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #444; + text-decoration: underline; +} + +div.related { + background-color: #6BA81E; + line-height: 32px; + color: #fff; + text-shadow: 0px 1px 0 #444; + font-size: 0.80em; +} + +div.related a { + color: #E2F3CC; +} + +div.sphinxsidebar { + font-size: 0.75em; + line-height: 1.5em; + width: 300px +} + +div.sphinxsidebarwrapper{ + padding: 20px 0; +} + +div.sphinxsidebar h3, +div.sphinxsidebar h4 { + font-family: Arial, sans-serif; + color: #222; + font-size: 1.2em; + font-weight: normal; + margin: 0; + padding: 5px 10px; + background-color: #ddd; + text-shadow: 1px 1px 0 white +} + +div.sphinxsidebar h4{ + font-size: 1.1em; +} + +div.sphinxsidebar h3 a { + color: #444; +} + + +div.sphinxsidebar p { + color: #888; + padding: 5px 20px; +} + +div.sphinxsidebar p.topless { +} + +div.sphinxsidebar ul { + margin: 10px 10px 10px 20px; + padding: 0; + color: #000; +} + +div.sphinxsidebar a { + color: #444; +} + +div.sphinxsidebar input { + border: 1px solid #ccc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar input[type=text]{ + margin-left: 20px; +} + +/* -- body styles ----------------------------------------------------------- */ + +a { + color: #005B81; + text-decoration: none; +} + +a:hover { + color: #E32E00; + text-decoration: underline; +} + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: Arial, sans-serif; + background-color: #BED4EB; + font-weight: normal; + color: #212224; + margin: 30px 0px 10px 0px; + padding: 5px 0 5px 10px; + text-shadow: 0px 1px 0 white +} + +div.body h1 { border-top: 20px solid white; margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 150%; background-color: #C8D5E3; } +div.body h3 { font-size: 120%; background-color: #D8DEE3; } +div.body h4 { font-size: 110%; background-color: #D8DEE3; } +div.body h5 { font-size: 100%; background-color: #D8DEE3; } +div.body h6 { font-size: 100%; background-color: #D8DEE3; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + line-height: 1.5em; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.highlight{ + background-color: white; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 10px; + background-color: White; + color: #222; + line-height: 1.2em; + border: 1px solid #C6C9CB; + font-size: 1.2em; + margin: 1.5em 0 1.5em 0; + -webkit-box-shadow: 1px 1px 1px #d8d8d8; + -moz-box-shadow: 1px 1px 1px #d8d8d8; +} + +tt { + background-color: #ecf0f3; + color: #222; + padding: 1px 2px; + font-size: 1.2em; + font-family: monospace; +} diff --git a/docs/_theme/nature/static/pygments.css b/docs/_theme/nature/static/pygments.css new file mode 100644 index 00000000..652b7612 --- /dev/null +++ b/docs/_theme/nature/static/pygments.css @@ -0,0 +1,54 @@ +.c { color: #999988; font-style: italic } /* Comment */ +.k { font-weight: bold } /* Keyword */ +.o { font-weight: bold } /* Operator */ +.cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.cp { color: #999999; font-weight: bold } /* Comment.preproc */ +.c1 { color: #999988; font-style: italic } /* Comment.Single */ +.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.ge { font-style: italic } /* Generic.Emph */ +.gr { color: #aa0000 } /* Generic.Error */ +.gh { color: #999999 } /* Generic.Heading */ +.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.go { color: #111 } /* Generic.Output */ +.gp { color: #555555 } /* Generic.Prompt */ +.gs { font-weight: bold } /* Generic.Strong */ +.gu { color: #aaaaaa } /* Generic.Subheading */ +.gt { color: #aa0000 } /* Generic.Traceback */ +.kc { font-weight: bold } /* Keyword.Constant */ +.kd { font-weight: bold } /* Keyword.Declaration */ +.kp { font-weight: bold } /* Keyword.Pseudo */ +.kr { font-weight: bold } /* Keyword.Reserved */ +.kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.m { color: #009999 } /* Literal.Number */ +.s { color: #bb8844 } /* Literal.String */ +.na { color: #008080 } /* Name.Attribute */ +.nb { color: #999999 } /* Name.Builtin */ +.nc { color: #445588; font-weight: bold } /* Name.Class */ +.no { color: #ff99ff } /* Name.Constant */ +.ni { color: #800080 } /* Name.Entity */ +.ne { color: #990000; font-weight: bold } /* Name.Exception */ +.nf { color: #990000; font-weight: bold } /* Name.Function */ +.nn { color: #555555 } /* Name.Namespace */ +.nt { color: #000080 } /* Name.Tag */ +.nv { color: purple } /* Name.Variable */ +.ow { font-weight: bold } /* Operator.Word */ +.mf { color: #009999 } /* Literal.Number.Float */ +.mh { color: #009999 } /* Literal.Number.Hex */ +.mi { color: #009999 } /* Literal.Number.Integer */ +.mo { color: #009999 } /* Literal.Number.Oct */ +.sb { color: #bb8844 } /* Literal.String.Backtick */ +.sc { color: #bb8844 } /* Literal.String.Char */ +.sd { color: #bb8844 } /* Literal.String.Doc */ +.s2 { color: #bb8844 } /* Literal.String.Double */ +.se { color: #bb8844 } /* Literal.String.Escape */ +.sh { color: #bb8844 } /* Literal.String.Heredoc */ +.si { color: #bb8844 } /* Literal.String.Interpol */ +.sx { color: #bb8844 } /* Literal.String.Other */ +.sr { color: #808000 } /* Literal.String.Regex */ +.s1 { color: #bb8844 } /* Literal.String.Single */ +.ss { color: #bb8844 } /* Literal.String.Symbol */ +.bp { color: #999999 } /* Name.Builtin.Pseudo */ +.vc { color: #ff99ff } /* Name.Variable.Class */ +.vg { color: #ff99ff } /* Name.Variable.Global */ +.vi { color: #ff99ff } /* Name.Variable.Instance */ +.il { color: #009999 } /* Literal.Number.Integer.Long */
\ No newline at end of file diff --git a/docs/_theme/nature/theme.conf b/docs/_theme/nature/theme.conf new file mode 100644 index 00000000..1cc40044 --- /dev/null +++ b/docs/_theme/nature/theme.conf @@ -0,0 +1,4 @@ +[theme] +inherit = basic +stylesheet = nature.css +pygments_style = tango diff --git a/docs/conf.py b/docs/conf.py index d4ff4a15..bad1a578 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -16,20 +16,19 @@ import sys, os -# If your extensions are in another directory, add it here. If the directory -# is relative to the documentation root, use os.path.abspath to make it -# absolute, like shown here. +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.append(os.path.abspath('.')) -# General configuration -# --------------------- +# -- General configuration ----------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] # Add any paths that contain templates here, relative to this directory. -templates_path = ['.templates'] +templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.txt' @@ -49,9 +48,9 @@ copyright = u'2009, The fellowship of the packaging' # built documents. # # The short X.Y version. -version = '0.6.1' +version = '0.6.4' # The full version, including alpha/beta/rc tags. -release = '0.6.1' +release = '0.6.4' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -87,21 +86,30 @@ exclude_trees = [] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] -# Options for HTML output -# ----------------------- -# The style sheet to use for HTML and HTML Help pages. A file of that name -# must exist either in Sphinx' static/ path, or in one of the custom paths -# given in html_static_path. -html_style = 'default.css' +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. Major themes that come with +# Sphinx are currently 'default' and 'sphinxdoc'. +html_theme = 'nature' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = ['_theme'] # The name for this set of Sphinx documents. If None, it defaults to # "<project> v<release> documentation". -#html_title = None +html_title = "Distribute documentation" # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +html_short_title = "Distribute" # The name of an image file (relative to this directory) to place at the top # of the sidebar. @@ -115,7 +123,7 @@ html_style = 'default.css' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['.static'] +#html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. @@ -141,8 +149,8 @@ html_static_path = ['.static'] # If true, the index is split into individual pages for each letter. #html_split_index = False -# If true, the reST sources are included in the HTML build as _sources/<name>. -#html_copy_source = True +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True # If true, an OpenSearch description file will be output, and all pages will # contain a <link> tag referring to it. The value of this option must be the @@ -156,8 +164,7 @@ html_static_path = ['.static'] htmlhelp_basename = 'Distributedoc' -# Options for LaTeX output -# ------------------------ +# -- Options for LaTeX output -------------------------------------------------- # The paper size ('letter' or 'a4'). #latex_paper_size = 'letter' @@ -166,7 +173,7 @@ htmlhelp_basename = 'Distributedoc' #latex_font_size = '10pt' # Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, document class [howto/manual]). +# (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('index', 'Distribute.tex', ur'Distribute Documentation', ur'The fellowship of the packaging', 'manual'), diff --git a/docs/easy_install.txt b/docs/easy_install.txt index ff0ad3d8..b821e5ca 100644 --- a/docs/easy_install.txt +++ b/docs/easy_install.txt @@ -330,7 +330,9 @@ to restrict downloading to hosts in your own intranet. See the section below on `Command-Line Options`_ for more details on the ``--allow-hosts`` option. By default, there are no host restrictions in effect, but you can change this -default by editing the appropriate `configuration files`_ and adding:: +default by editing the appropriate `configuration files`_ and adding: + +.. code-block:: ini [easy_install] allow_hosts = *.myintranet.example.com,*.python.org @@ -411,7 +413,9 @@ generated directory listing (such as the Apache web server provides). If you are setting up an intranet site for package downloads, you may want to configure the target machines to use your download site by default, adding -something like this to their `configuration files`_:: +something like this to their `configuration files`_: + +.. code-block:: ini [easy_install] find_links = http://mypackages.example.com/somedir/ @@ -445,7 +449,9 @@ Controlling Build Options EasyInstall respects standard distutils `Configuration Files`_, so you can use them to configure build options for packages that it installs from source. For example, if you are on Windows using the MinGW compiler, you can configure the -default compiler by putting something like this:: +default compiler by putting something like this: + +.. code-block:: ini [build] compiler = mingw32 @@ -593,7 +599,9 @@ distutils configuration files, under the command heading ``easy_install``. EasyInstall will look first for a ``setup.cfg`` file in the current directory, then a ``~/.pydistutils.cfg`` or ``$HOME\\pydistutils.cfg`` (on Unix-like OSes and Windows, respectively), and finally a ``distutils.cfg`` file in the -``distutils`` package directory. Here's a simple example:: +``distutils`` package directory. Here's a simple example: + +.. code-block:: ini [easy_install] @@ -986,7 +994,9 @@ The next step is to create or modify ``distutils.cfg`` in the ``distutils`` directory of your Python library. The correct directory will be something like ``/usr/lib/python2.X/distutils`` on most Posix systems and something like ``C:\\Python2X\Lib\distutils`` on Windows machines. Add the following lines -to the file, substituting the correct Python version if necessary:: +to the file, substituting the correct Python version if necessary: + +.. code-block:: ini [install] install_lib = ~/lib/python2.3 @@ -1031,7 +1041,9 @@ location, because it is already configured to process ``.pth`` files, and EasyInstall already knows this. Before installing EasyInstall/setuptools, just create a ``~/.pydistutils.cfg`` -file with the following contents (or add this to the existing contents):: +file with the following contents (or add this to the existing contents): + +.. code-block:: ini [install] install_lib = ~/Library/Python/$py_version_short/site-packages @@ -1105,7 +1117,9 @@ Assuming that you want to install packages in a directory called ``~/py-lib``, and scripts in ``~/bin``, here's what you need to do: First, edit ``~/.pydistutils.cfg`` to include these settings, if you don't -already have them:: +already have them: + +.. code-block:: ini [install] install_lib = ~/py-lib diff --git a/docs/python3.txt b/docs/python3.txt index 9b5fa797..d5c3da67 100644 --- a/docs/python3.txt +++ b/docs/python3.txt @@ -36,20 +36,21 @@ to a list of names of packages containing fixers. A typical setup.py can look something like this:: - from setuptools import setup - - setup(name='your.module', - version = '1.0', - description='This is your awesome module', - author='You', - author_email='your@email', - package_dir = {'': 'src'}, - packages = ['your', 'you.module'], - test_suite = 'your.module.tests', - use_2to3 = True, - convert_2to3_doctests = ['src/your/module/README.txt'], - use_2to3_fixers = ['your.fixers'] - ) + from setuptools import setup + + setup( + name='your.module', + version = '1.0', + description='This is your awesome module', + author='You', + author_email='your@email', + package_dir = {'': 'src'}, + packages = ['your', 'you.module'], + test_suite = 'your.module.tests', + use_2to3 = True, + convert_2to3_doctests = ['src/your/module/README.txt'], + use_2to3_fixers = ['your.fixers'] + ) Differential conversion ----------------------- @@ -96,25 +97,26 @@ install process will continue as normal, but if you want to get rid of that error this is easy. Simply conditionally add the new parameters into an extra dict and pass that dict into setup():: - from setuptools import setup - import sys - - extra = {} - if sys.version_info >= (3,): - extra['use_2to3'] = True - extra['convert_2to3_doctests'] = ['src/your/module/README.txt'] - extra['use_2to3_fixers'] = ['your.fixers'] - - setup(name='your.module', - version = '1.0', - description='This is your awesome module', - author='You', - author_email='your@email', - package_dir = {'': 'src'}, - packages = ['your', 'you.module'], - test_suite = 'your.module.tests', - **extra - ) + from setuptools import setup + import sys + + extra = {} + if sys.version_info >= (3,): + extra['use_2to3'] = True + extra['convert_2to3_doctests'] = ['src/your/module/README.txt'] + extra['use_2to3_fixers'] = ['your.fixers'] + + setup( + name='your.module', + version = '1.0', + description='This is your awesome module', + author='You', + author_email='your@email', + package_dir = {'': 'src'}, + packages = ['your', 'you.module'], + test_suite = 'your.module.tests', + **extra + ) This way the parameters will only be used under Python 3, where you have to use Distribute. diff --git a/docs/setuptools.txt b/docs/setuptools.txt index 06f632ec..d5bd98b5 100644 --- a/docs/setuptools.txt +++ b/docs/setuptools.txt @@ -141,7 +141,7 @@ dependencies, and perhaps some data files and scripts:: '': ['*.txt', '*.rst'], # And include any *.msg files found in the 'hello' package, too: 'hello': ['*.msg'], - } + }, # metadata for upload to PyPI author = "Me", @@ -1117,7 +1117,9 @@ if they do, it might not be the right version. Fixing this is easy; just download `distribute_setup.py`_, and put it in the same directory as your ``setup.py`` script. (Be sure to add it to your revision control system, too.) Then add these two lines to the very top of your setup script, before the script imports -anything from setuptools:: +anything from setuptools: + +.. code-block:: python import distribute_setup distribute_setup.use_setuptools() @@ -1573,7 +1575,9 @@ Managing "Continuous Releases" Using Subversion If you expect your users to track in-development versions of your project via Subversion, there are a few additional steps you should take to ensure that things work smoothly with EasyInstall. First, you should add the following -to your project's ``setup.cfg`` file:: +to your project's ``setup.cfg`` file: + +.. code-block:: ini [egg_info] tag_build = .dev @@ -1603,7 +1607,9 @@ their checkout URL (as described in the previous section) with an to download ``projectname==dev`` in order to get the latest in-development code. Note that if your project depends on such in-progress code, you may wish to specify your ``install_requires`` (or other requirements) to include -``==dev``, e.g.:: +``==dev``, e.g.: + +.. code-block:: python install_requires = ["OtherProject>=0.2a1.dev-r143,==dev"] @@ -2369,6 +2375,63 @@ The ``upload`` command has a few options worth noting: The URL of the repository to upload to. Defaults to http://pypi.python.org/pypi (i.e., the main PyPI installation). +.. _upload_docs: + +``upload_docs`` - Upload package documentation to PyPI +====================================================== + +PyPI now supports uploading project documentation to the dedicated URL +http://packages.python.org/<project>/. + +The ``upload_docs`` command will create the necessary zip file out of a +documentation directory and will post to the repository. + +Note that to upload the documentation of a project, the corresponding version +must already be registered with PyPI, using the distutils ``register`` +command -- just like the ``upload`` command. + +Assuming there is an ``Example`` project with documentation in the +subdirectory ``docs``, e.g.:: + + Example/ + |-- example.py + |-- setup.cfg + |-- setup.py + |-- docs + | |-- build + | | `-- html + | | | |-- index.html + | | | `-- tips_tricks.html + | |-- conf.py + | |-- index.txt + | `-- tips_tricks.txt + +You can simply pass the documentation directory path to the ``upload_docs`` +command:: + + python setup.py upload_docs --upload-dir=docs/build/html + +As with any other ``setuptools`` based command, you can define useful +defaults in the ``setup.cfg`` of your Python project, e.g.: + +.. code-block:: ini + + [upload_docs] + upload-dir = docs/build/html + +The ``upload_docs`` command has the following options: + +``--upload-dir`` + The directory to be uploaded to the repository. + +``--show-response`` + Display the full response text from server; this is useful for debugging + PyPI problems. + +``--repository=URL, -r URL`` + The URL of the repository to upload to. Defaults to + http://pypi.python.org/pypi (i.e., the main PyPI installation). + ------------------------------------ Extending and Reusing ``setuptools`` @@ -2539,7 +2602,9 @@ all the filenames within that directory (and any subdirectories thereof) that are under revision control. For example, if you were going to create a plugin for a revision control system -called "foobar", you would write a function something like this:: +called "foobar", you would write a function something like this: + +.. code-block:: python def find_files_for_foobar(dirname): # loop to yield paths that start with `dirname` @@ -6,3 +6,11 @@ tag_svn_revision = 1 release = egg_info -RDb '' source = register sdist binary binary = bdist_egg upload --show-response + +[build_sphinx] +source-dir = docs/ +build-dir = docs/build +all_files = 1 + +[upload_docs] +upload-dir = docs/build/html
\ No newline at end of file @@ -134,6 +134,7 @@ dist = setup( License :: OSI Approved :: Zope Public License Operating System :: OS Independent Programming Language :: Python + Programming Language :: Python :: 3 Topic :: Software Development :: Libraries :: Python Modules Topic :: System :: Archiving :: Packaging Topic :: System :: Systems Administration diff --git a/setuptools/command/__init__.py b/setuptools/command/__init__.py index f898822b..ea544b50 100644 --- a/setuptools/command/__init__.py +++ b/setuptools/command/__init__.py @@ -2,7 +2,7 @@ __all__ = [ 'alias', 'bdist_egg', 'bdist_rpm', 'build_ext', 'build_py', 'develop', 'easy_install', 'egg_info', 'install', 'install_lib', 'rotate', 'saveopts', 'sdist', 'setopt', 'test', 'upload', 'install_egg_info', 'install_scripts', - 'register', 'bdist_wininst', + 'register', 'bdist_wininst', 'upload_docs', ] import sys diff --git a/setuptools/command/upload_docs.py b/setuptools/command/upload_docs.py new file mode 100644 index 00000000..5bbdc7f2 --- /dev/null +++ b/setuptools/command/upload_docs.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +"""upload_docs + +Implements a Distutils 'upload_docs' subcommand (upload documentation to +PyPI's packages.python.org). +""" + +import os +import socket +import zipfile +import httplib +import base64 +import urlparse +import tempfile +import cStringIO as StringIO + +from distutils import log +from distutils.errors import DistutilsOptionError +from distutils.command.upload import upload + +class upload_docs(upload): + + description = 'Upload documentation to PyPI' + + user_options = [ + ('repository=', 'r', + "url of repository [default: %s]" % upload.DEFAULT_REPOSITORY), + ('show-response', None, + 'display full response text from server'), + ('upload-dir=', None, 'directory to upload'), + ] + boolean_options = upload.boolean_options + + def initialize_options(self): + upload.initialize_options(self) + self.upload_dir = None + + def finalize_options(self): + upload.finalize_options(self) + if self.upload_dir is None: + build = self.get_finalized_command('build') + self.upload_dir = os.path.join(build.build_base, 'docs') + self.mkpath(self.upload_dir) + self.ensure_dirname('upload_dir') + self.announce('Using upload directory %s' % self.upload_dir) + + def create_zipfile(self): + name = self.distribution.metadata.get_name() + tmp_dir = tempfile.mkdtemp() + tmp_file = os.path.join(tmp_dir, "%s.zip" % name) + zip_file = zipfile.ZipFile(tmp_file, "w") + for root, dirs, files in os.walk(self.upload_dir): + if not files: + raise DistutilsOptionError( + "no files found in upload directory '%s'" + % self.upload_dir) + for name in files: + full = os.path.join(root, name) + relative = root[len(self.upload_dir):].lstrip(os.path.sep) + dest = os.path.join(relative, name) + zip_file.write(full, dest) + zip_file.close() + return tmp_file + + def run(self): + zip_file = self.create_zipfile() + self.upload_file(zip_file) + + def upload_file(self, filename): + content = open(filename, 'rb').read() + meta = self.distribution.metadata + data = { + ':action': 'doc_upload', + 'name': meta.get_name(), + 'content': (os.path.basename(filename), content), + } + # set up the authentication + auth = "Basic " + base64.encodestring( + self.username + ":" + self.password).strip() + + # Build up the MIME payload for the POST data + boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' + sep_boundary = '\n--' + boundary + end_boundary = sep_boundary + '--' + body = StringIO.StringIO() + for key, value in data.items(): + # handle multiple entries for the same name + if type(value) != type([]): + value = [value] + for value in value: + if type(value) is tuple: + fn = ';filename="%s"' % value[0] + value = value[1] + else: + fn = "" + value = str(value) + body.write(sep_boundary) + body.write('\nContent-Disposition: form-data; name="%s"'%key) + body.write(fn) + body.write("\n\n") + body.write(value) + if value and value[-1] == '\r': + body.write('\n') # write an extra newline (lurve Macs) + body.write(end_boundary) + body.write("\n") + body = body.getvalue() + + self.announce("Submitting documentation to %s" % (self.repository), + log.INFO) + + # build the Request + # We can't use urllib2 since we need to send the Basic + # auth right with the first request + schema, netloc, url, params, query, fragments = \ + urlparse.urlparse(self.repository) + assert not params and not query and not fragments + if schema == 'http': + http = httplib.HTTPConnection(netloc) + elif schema == 'https': + http = httplib.HTTPSConnection(netloc) + else: + raise AssertionError("unsupported schema "+schema) + + data = '' + loglevel = log.INFO + try: + http.connect() + http.putrequest("POST", url) + http.putheader('Content-type', + 'multipart/form-data; boundary=%s'%boundary) + http.putheader('Content-length', str(len(body))) + http.putheader('Authorization', auth) + http.endheaders() + http.send(body) + except socket.error, e: + self.announce(str(e), log.ERROR) + return + + r = http.getresponse() + if r.status == 200: + self.announce('Server response (%s): %s' % (r.status, r.reason), + log.INFO) + elif r.status == 301: + location = r.getheader('Location') + if location is None: + location = 'http://packages.python.org/%s/' % meta.get_name() + self.announce('Upload successful. Visit %s' % location, + log.INFO) + else: + self.announce('Upload failed (%s): %s' % (r.status, r.reason), + log.ERROR) + if self.show_response: + print '-'*75, r.read(), '-'*75 |
